Announcement

Collapse
No announcement yet.

Hacking 1.6 again for refks

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hacking 1.6 again for refks

    Alright, so let's get to it, we need Ollydbg and IDA, obviously. Let's remember since 2008 or so, or maybe it was later? Valve finally dumped their old "custom" pe scheme. Since then it's become a simple matter of using exported functions to track things down.

    Now you could in theory decide to directly do IAT hooking like in days yonder, but that is not necessary.

    First recall that the client table is actually exported from client.dll and they call GetProcAddress to retrieve the exports.

    hw.dll + 0xB1E0

    Oh look lots of fun strings, and they're all from client.dll... Naturally. Now you can sig or use something and replace each entry or do a giant memcpy. I don't care. I'll actually write up something next post, along with OpenGL and other fun stuff.

    Note that the lovely giant OpenGL table I used to hook seems to have been replaced with calls to the import. Ok, great. No problem.

    Edit: Some of the hw.dll funcs and client(?) seem to STILL have those LOVELY nullstubs. Folks it's LTFX time.

    hw.dll + 0x61F80

    Oh my ... what have we here? YUM.

    So all the tools I need are written up. December is crunch time. I'll try to write at least one post a day covering one aspect or portion thereof, and a github to organize everything.

    Building from my previous post, earlier last month. We noticed that all the goodies are neatly exported. Hooking is merely a question of overwriting the function pointers in the table. Ideally you'd want to overwrite every pointer just as a precaution.

    How so?

    First we need the index into the table for each function. However we also need the size of the table.

    The indices are as follows:

    0: Initialize
    1: HUD_Init
    2: HUD_VidInit
    3: HUD_Redraw
    4: HUD_UpdateClientData
    5: HUD_Reset
    6: HUD_PlayerMove
    7: HUD_PlayerMoveInit
    8: HUD_PlayerMoveTexture
    9: IN_ActivateMouse
    10: IN_DeactivateMouse
    11: IN_MouseEvent
    12: IN_ClearStates
    13: IN_Accumulate
    14: CL_CreateMove
    15: CL_IsThirdPerson
    16: CL_CameraOffset
    17: KB_Find
    18: CAM_Think
    19: V_CalcRefDef
    20: HUD_AddEntity
    21: HUD_CreateEntities
    22: HUD_DrawNormalTriangles
    23: HUD_DrawTransparentTriangles
    24: HUD_StudioEvent
    25: HUD_PostRunCmd
    26: HUD_ShutDown
    27: HUD_TxferLocalOverrides
    28: HUD_ProcessPlayerState
    29: HUD_TxferPredictionData
    30: Demo_ReadBuffer
    31: HUD_ConnectionlessPacket
    32: HUD_GetHullBounds
    33: HUD_Frame
    34: HUD_Key_Event
    35: HUD_TempEntUpdate
    36: HUD_GetUserEntity
    37: HUD_VoiceStatus
    38: HUD_DirectorMessage
    39: HUD_GetStudioModelInterface
    40: HUD_ChatInputPosition
    41: HUD_GetPlayerTeam
    42: ClientFactory

    For a grand total obviously of 43 entries.

    You merely need to pattern scan for the table. If you cross reference it, you'll note that there are 6 places where the table is referenced. Your choice, you can't go wrong anyway.

    Alternatively and this is a definite option. You can rely on the nullstubs that the engine still has and hook those, remember you'll need a to use a ltfx style hookgate to get the job done, but it works just as well, and I sorta prefer that.

    So once you have your pointer, simply:

    Code:
    uintptr_t* pClientFunctionTable = ( uintptr_t* )pTable;
    
    pClientFunctionTable [ index_of_client_function ] = &YourFunction; // or ( uintptr_t )YourFunction

    Alternatively:
    Code:
     uintptr_t* pClientFunctionTable = ( uintptr_t* )pTable;
    
    memcpy ( pClientFunctionTable, &HookedClientFunctionTable, sizeof ( ClientFunctions_t ) );
    Assuming you can match the server's framerate tit for tat, you can properly predict and decay the pitch punchangle. Yaw on the other hand, not so much. Since even if you can match the framerate, assuming that you generate the proper angle, you still have a 50/50 chance of getting the sign right or wrong.

    That's not even noting that punchangles are delayed by ping and the compression just sucks.

    Perfect NoSpread over a limited domain of pitch angles is doable, thus I posted LPNoSpread. I won't post the full solution, as I've already given it almost away in another thread. Perfect autowall just involves fixing up snipity's awall to 1.6 values, initing the texture types, and fixing his trace code. Easy. Why dumbass cheat server kids use LTFX's dwall even recently surprises me, but what do I expect of them?

    For the record, snipity, ltfx, and all trum3n were Americans. We are the best and you just can't deal with it. Tabris, P47R!CK, RaptorFactor, Tammimego, Araz, and others earned honorary American citizenship by being trus.


    Depends on the weapon, but if your ping isn't higher than the firerate then you
    should be lucky enough to correct the sign from received server update before you fire next shot


    In a perfect world yes, you'd have a 75% chance of getting the yaw punchangle right.

    Like I said before it's ping delayed and they don't use the shared seed for some things, and the compression butchers it. The only thing that's good is you get to know the sign, but again with ping delay, you can really be screwed over.

    One feature I've never seen in another hack is correcting the elites so they fire center.


    Good enough that the trace code is back from quake days so not that advanced

    Thankfully it's not.






  • #2
    As I noted in an earlier post the nullstubs in hw.dll are still there. So how do we exploit this? First we need to know what we're looking for. Recall that a nullstub is a call that simply returns.

    So:
    Code:
    __declspec ( naked ) void Nullstub ( void )
    {
    return;
    }

    In a nutshell.

    How can we exploit this giant table to do our hooks? Recall how most game hooks work, they work by hooking the vtable or a pointer or redirecting execution ( byte patching, hw bp, exception hooking, etc ). In our case we simply need to find a nullstub called by the client or engine code we want to hook. Once we've found it we need to apply a return address check. I know what you're thinking, and you're right it will tell us only that we're going to return to say this point in client.dll or hw.dll. Correct, and we can use that information to know which client function or engine function called us without having to walk the stack at this point.

    However to do anything meaningful we need to find the caller's return address and overwrite it. Once we've done that, once the function returns it will return to our jumpgate and we can do our code as normal, in the case of V_CalcRefDef we'd do a pre and post hook.

    Code:
    if ( ( uintptr_t )_ReturnAddress() == address_of_interest )
    {
    // branch into our code below
    }
    else
    {
    // no
    }
    Now if we branch, then we apply the following logic.

    push edx
    push eax
    mov edx, dword ptr ss:[esp+offset_to_caller_return]
    mov eax, ourgate
    mov origreturn, edx
    mov dword ptr ss:[esp+offset_to_caller_return], eax
    nop
    pop eax
    pop edx
    retn
    Succinctly speaking that is.

    Now if you're familiar with the LTFX slots hooking or SlotsFX this is familiar but you're probably like you moron you don't need to do that. Well yes I do because that table applied only to client functions, not engine functions. That table is also GONE. So yeah, thanks for playing sport. See you later.

    03A91F80 55 PUSH EBP
    03A91F81 8BEC MOV EBP,ESP
    03A91F83 81EC 90020000 SUB ESP,290
    03A91F89 A1 280E0704 MOV EAX,DWORD PTR DS:[4070E28]
    03A91F8E 53 PUSH EBX
    03A91F8F 33DB XOR EBX,EBX
    03A91F91 3BC3 CMP EAX,EBX
    03A91F93 0F84 F2030000 JE hw.03A9238B
    03A91F99 B8 501DA903 MOV EAX,hw.03A91D50
    03A91F9E 8985 58FFFFFF MOV DWORD PTR SS:[EBP-A8],EAX
    03A91FA4 8985 5CFFFFFF MOV DWORD PTR SS:[EBP-A4],EAX
    03A91FAA 8985 60FFFFFF MOV DWORD PTR SS:[EBP-A0],EAX
    03A91FB0 8985 64FFFFFF MOV DWORD PTR SS:[EBP-9C],EAX
    03A91FB6 8985 68FFFFFF MOV DWORD PTR SS:[EBP-98],EAX
    03A91FBC 8985 6CFFFFFF MOV DWORD PTR SS:[EBP-94],EAX
    03A91FC2 8985 70FFFFFF MOV DWORD PTR SS:[EBP-90],EAX
    03A91FC8 8985 74FFFFFF MOV DWORD PTR SS:[EBP-8C],EAX
    03A91FCE 8985 78FFFFFF MOV DWORD PTR SS:[EBP-88],EAX
    03A91FD4 8985 7CFFFFFF MOV DWORD PTR SS:[EBP-84],EAX
    03A91FDA 8945 80 MOV DWORD PTR SS:[EBP-80],EAX
    03A91FDD 8945 84 MOV DWORD PTR SS:[EBP-7C],EAX
    03A91FE0 8945 88 MOV DWORD PTR SS:[EBP-78],EAX
    03A91FE3 8945 8C MOV DWORD PTR SS:[EBP-74],EAX
    03A91FE6 8945 90 MOV DWORD PTR SS:[EBP-70],EAX
    03A91FE9 8945 94 MOV DWORD PTR SS:[EBP-6C],EAX
    03A91FEC 8945 98 MOV DWORD PTR SS:[EBP-68],EAX
    03A91FEF 8945 9C MOV DWORD PTR SS:[EBP-64],EAX
    03A91FF2 8945 A0 MOV DWORD PTR SS:[EBP-60],EAX
    03A91FF5 8945 A4 MOV DWORD PTR SS:[EBP-5C],EAX
    03A91FF8 8945 A8 MOV DWORD PTR SS:[EBP-58],EAX
    03A91FFB 8945 AC MOV DWORD PTR SS:[EBP-54],EAX
    03A91FFE 8945 B0 MOV DWORD PTR SS:[EBP-50],EAX
    03A92001 8945 B4 MOV DWORD PTR SS:[EBP-4C],EAX
    03A92004 8945 B8 MOV DWORD PTR SS:[EBP-48],EAX
    03A92007 8945 BC MOV DWORD PTR SS:[EBP-44],EAX
    03A9200A 8945 C0 MOV DWORD PTR SS:[EBP-40],EAX
    03A9200D 8945 C4 MOV DWORD PTR SS:[EBP-3C],EAX
    03A92010 8945 C8 MOV DWORD PTR SS:[EBP-38],EAX
    03A92013 8945 CC MOV DWORD PTR SS:[EBP-34],EAX
    03A92016 8945 D0 MOV DWORD PTR SS:[EBP-30],EAX
    03A92019 8945 D4 MOV DWORD PTR SS:[EBP-2C],EAX
    03A9201C 8945 D8 MOV DWORD PTR SS:[EBP-28],EAX
    03A9201F 8945 DC MOV DWORD PTR SS:[EBP-24],EAX
    03A92022 8945 E0 MOV DWORD PTR SS:[EBP-20],EAX
    03A92025 8945 E4 MOV DWORD PTR SS:[EBP-1C],EAX
    03A92028 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX
    03A9202B 8945 EC MOV DWORD PTR SS:[EBP-14],EAX
    03A9202E 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX
    03A92031 8945 F4 MOV DWORD PTR SS:[EBP-C],EAX
    03A92034 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
    03A92037 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
    03A9203A 8985 70FDFFFF MOV DWORD PTR SS:[EBP-290],EAX
    03A92040 8985 74FDFFFF MOV DWORD PTR SS:[EBP-28C],EAX
    03A92046 8985 78FDFFFF MOV DWORD PTR SS:[EBP-288],EAX
    03A9204C 8985 7CFDFFFF MOV DWORD PTR SS:[EBP-284],EAX
    03A92052 8985 80FDFFFF MOV DWORD PTR SS:[EBP-280],EAX
    03A92058 8985 84FDFFFF MOV DWORD PTR SS:[EBP-27C],EAX
    03A9205E 8985 88FDFFFF MOV DWORD PTR SS:[EBP-278],EAX
    03A92064 8985 8CFDFFFF MOV DWORD PTR SS:[EBP-274],EAX
    03A9206A 8985 90FDFFFF MOV DWORD PTR SS:[EBP-270],EAX
    03A92070 8985 94FDFFFF MOV DWORD PTR SS:[EBP-26C],EAX
    03A92076 8985 98FDFFFF MOV DWORD PTR SS:[EBP-268],EAX
    03A9207C 8985 9CFDFFFF MOV DWORD PTR SS:[EBP-264],EAX
    03A92082 8985 A0FDFFFF MOV DWORD PTR SS:[EBP-260],EAX
    03A92088 8985 A4FDFFFF MOV DWORD PTR SS:[EBP-25C],EAX
    03A9208E 8985 A8FDFFFF MOV DWORD PTR SS:[EBP-258],EAX
    03A92094 8985 ACFDFFFF MOV DWORD PTR SS:[EBP-254],EAX
    03A9209A 8985 B0FDFFFF MOV DWORD PTR SS:[EBP-250],EAX
    03A920A0 8985 B4FDFFFF MOV DWORD PTR SS:[EBP-24C],EAX
    03A920A6 8985 B8FDFFFF MOV DWORD PTR SS:[EBP-248],EAX
    03A920AC 8985 BCFDFFFF MOV DWORD PTR SS:[EBP-244],EAX
    03A920B2 8985 C0FDFFFF MOV DWORD PTR SS:[EBP-240],EAX
    03A920B8 8985 C4FDFFFF MOV DWORD PTR SS:[EBP-23C],EAX
    03A920BE 8985 C8FDFFFF MOV DWORD PTR SS:[EBP-238],EAX
    03A920C4 8985 CCFDFFFF MOV DWORD PTR SS:[EBP-234],EAX
    03A920CA 8985 D0FDFFFF MOV DWORD PTR SS:[EBP-230],EAX
    03A920D0 8985 D4FDFFFF MOV DWORD PTR SS:[EBP-22C],EAX
    03A920D6 8985 D8FDFFFF MOV DWORD PTR SS:[EBP-228],EAX
    03A920DC 8985 DCFDFFFF MOV DWORD PTR SS:[EBP-224],EAX
    03A920E2 8985 E0FDFFFF MOV DWORD PTR SS:[EBP-220],EAX
    03A920E8 8985 E4FDFFFF MOV DWORD PTR SS:[EBP-21C],EAX
    03A920EE 8985 E8FDFFFF MOV DWORD PTR SS:[EBP-218],EAX
    03A920F4 8985 ECFDFFFF MOV DWORD PTR SS:[EBP-214],EAX
    03A920FA 8985 F0FDFFFF MOV DWORD PTR SS:[EBP-210],EAX
    03A92100 8985 F4FDFFFF MOV DWORD PTR SS:[EBP-20C],EAX
    03A92106 8985 F8FDFFFF MOV DWORD PTR SS:[EBP-208],EAX
    03A9210C 8985 FCFDFFFF MOV DWORD PTR SS:[EBP-204],EAX
    03A92112 8985 00FEFFFF MOV DWORD PTR SS:[EBP-200],EAX
    03A92118 8985 04FEFFFF MOV DWORD PTR SS:[EBP-1FC],EAX
    03A9211E 8985 08FEFFFF MOV DWORD PTR SS:[EBP-1F8],EAX
    03A92124 8985 0CFEFFFF MOV DWORD PTR SS:[EBP-1F4],EAX
    03A9212A 8985 10FEFFFF MOV DWORD PTR SS:[EBP-1F0],EAX
    03A92130 8985 14FEFFFF MOV DWORD PTR SS:[EBP-1EC],EAX
    03A92136 8985 18FEFFFF MOV DWORD PTR SS:[EBP-1E8],EAX
    03A9213C 8985 1CFEFFFF MOV DWORD PTR SS:[EBP-1E4],EAX
    03A92142 8985 20FEFFFF MOV DWORD PTR SS:[EBP-1E0],EAX
    03A92148 8985 24FEFFFF MOV DWORD PTR SS:[EBP-1DC],EAX
    03A9214E 8985 28FEFFFF MOV DWORD PTR SS:[EBP-1D8],EAX
    03A92154 8985 2CFEFFFF MOV DWORD PTR SS:[EBP-1D4],EAX
    03A9215A 8985 30FEFFFF MOV DWORD PTR SS:[EBP-1D0],EAX
    03A92160 8985 34FEFFFF MOV DWORD PTR SS:[EBP-1CC],EAX
    03A92166 8985 38FEFFFF MOV DWORD PTR SS:[EBP-1C8],EAX
    03A9216C 8985 3CFEFFFF MOV DWORD PTR SS:[EBP-1C4],EAX
    03A92172 8985 40FEFFFF MOV DWORD PTR SS:[EBP-1C0],EAX
    03A92178 8985 44FEFFFF MOV DWORD PTR SS:[EBP-1BC],EAX
    03A9217E 8985 48FEFFFF MOV DWORD PTR SS:[EBP-1B8],EAX
    03A92184 8985 4CFEFFFF MOV DWORD PTR SS:[EBP-1B4],EAX
    03A9218A 8985 50FEFFFF MOV DWORD PTR SS:[EBP-1B0],EAX
    03A92190 8985 54FEFFFF MOV DWORD PTR SS:[EBP-1AC],EAX
    03A92196 8985 58FEFFFF MOV DWORD PTR SS:[EBP-1A8],EAX
    03A9219C 8985 5CFEFFFF MOV DWORD PTR SS:[EBP-1A4],EAX
    03A921A2 8985 60FEFFFF MOV DWORD PTR SS:[EBP-1A0],EAX
    03A921A8 8985 64FEFFFF MOV DWORD PTR SS:[EBP-19C],EAX
    03A921AE 8985 68FEFFFF MOV DWORD PTR SS:[EBP-198],EAX
    03A921B4 8985 6CFEFFFF MOV DWORD PTR SS:[EBP-194],EAX
    03A921BA 8985 70FEFFFF MOV DWORD PTR SS:[EBP-190],EAX
    03A921C0 8985 74FEFFFF MOV DWORD PTR SS:[EBP-18C],EAX
    03A921C6 8985 78FEFFFF MOV DWORD PTR SS:[EBP-188],EAX
    03A921CC 8985 7CFEFFFF MOV DWORD PTR SS:[EBP-184],EAX
    03A921D2 8985 80FEFFFF MOV DWORD PTR SS:[EBP-180],EAX
    03A921D8 8985 84FEFFFF MOV DWORD PTR SS:[EBP-17C],EAX
    03A921DE 8985 88FEFFFF MOV DWORD PTR SS:[EBP-178],EAX
    03A921E4 8985 8CFEFFFF MOV DWORD PTR SS:[EBP-174],EAX
    03A921EA 8985 90FEFFFF MOV DWORD PTR SS:[EBP-170],EAX
    03A921F0 8985 94FEFFFF MOV DWORD PTR SS:[EBP-16C],EAX
    03A921F6 8985 98FEFFFF MOV DWORD PTR SS:[EBP-168],EAX
    03A921FC 8985 9CFEFFFF MOV DWORD PTR SS:[EBP-164],EAX
    03A92202 8985 A0FEFFFF MOV DWORD PTR SS:[EBP-160],EAX
    03A92208 8985 A4FEFFFF MOV DWORD PTR SS:[EBP-15C],EAX
    03A9220E 8985 A8FEFFFF MOV DWORD PTR SS:[EBP-158],EAX
    03A92214 8985 ACFEFFFF MOV DWORD PTR SS:[EBP-154],EAX
    03A9221A 8985 B0FEFFFF MOV DWORD PTR SS:[EBP-150],EAX
    03A92220 8985 B4FEFFFF MOV DWORD PTR SS:[EBP-14C],EAX
    03A92226 899D B8FEFFFF MOV DWORD PTR SS:[EBP-148],EBX
    03A9222C 899D BCFEFFFF MOV DWORD PTR SS:[EBP-144],EBX
    03A92232 899D C0FEFFFF MOV DWORD PTR SS:[EBP-140],EBX
    03A92238 899D C4FEFFFF MOV DWORD PTR SS:[EBP-13C],EBX
    03A9223E 899D C8FEFFFF MOV DWORD PTR SS:[EBP-138],EBX
    03A92244 899D CCFEFFFF MOV DWORD PTR SS:[EBP-134],EBX
    03A9224A 8985 D0FEFFFF MOV DWORD PTR SS:[EBP-130],EAX
    03A92250 8985 D4FEFFFF MOV DWORD PTR SS:[EBP-12C],EAX
    03A92256 8985 D8FEFFFF MOV DWORD PTR SS:[EBP-128],EAX
    03A9225C 8985 DCFEFFFF MOV DWORD PTR SS:[EBP-124],EAX
    03A92262 8985 E0FEFFFF MOV DWORD PTR SS:[EBP-120],EAX
    03A92268 8985 E4FEFFFF MOV DWORD PTR SS:[EBP-11C],EAX
    03A9226E 8985 E8FEFFFF MOV DWORD PTR SS:[EBP-118],EAX
    03A92274 8985 ECFEFFFF MOV DWORD PTR SS:[EBP-114],EAX
    03A9227A 8985 F0FEFFFF MOV DWORD PTR SS:[EBP-110],EAX
    03A92280 8985 F4FEFFFF MOV DWORD PTR SS:[EBP-10C],EAX
    03A92286 8985 F8FEFFFF MOV DWORD PTR SS:[EBP-108],EAX
    03A9228C 8985 FCFEFFFF MOV DWORD PTR SS:[EBP-104],EAX
    03A92292 8985 00FFFFFF MOV DWORD PTR SS:[EBP-100],EAX
    03A92298 8985 04FFFFFF MOV DWORD PTR SS:[EBP-FC],EAX
    03A9229E 8985 08FFFFFF MOV DWORD PTR SS:[EBP-F8],EAX
    03A922A4 8985 0CFFFFFF MOV DWORD PTR SS:[EBP-F4],EAX
    03A922AA 8985 10FFFFFF MOV DWORD PTR SS:[EBP-F0],EAX
    03A922B0 8985 14FFFFFF MOV DWORD PTR SS:[EBP-EC],EAX
    03A922B6 8985 18FFFFFF MOV DWORD PTR SS:[EBP-E8],EAX
    03A922BC 8985 1CFFFFFF MOV DWORD PTR SS:[EBP-E4],EAX
    03A922C2 8985 20FFFFFF MOV DWORD PTR SS:[EBP-E0],EAX
    03A922C8 8985 24FFFFFF MOV DWORD PTR SS:[EBP-DC],EAX
    03A922CE 8985 28FFFFFF MOV DWORD PTR SS:[EBP-D8],EAX
    03A922D4 8985 2CFFFFFF MOV DWORD PTR SS:[EBP-D4],EAX
    03A922DA 8985 30FFFFFF MOV DWORD PTR SS:[EBP-D0],EAX
    03A922E0 8985 34FFFFFF MOV DWORD PTR SS:[EBP-CC],EAX
    03A922E6 8985 38FFFFFF MOV DWORD PTR SS:[EBP-C8],EAX
    03A922EC 8985 3CFFFFFF MOV DWORD PTR SS:[EBP-C4],EAX
    03A922F2 8985 40FFFFFF MOV DWORD PTR SS:[EBP-C0],EAX
    03A922F8 8985 44FFFFFF MOV DWORD PTR SS:[EBP-BC],EAX
    03A922FE 8985 48FFFFFF MOV DWORD PTR SS:[EBP-B8],EAX
    03A92304 8985 4CFFFFFF MOV DWORD PTR SS:[EBP-B4],EAX
    03A9230A 8985 50FFFFFF MOV DWORD PTR SS:[EBP-B0],EAX
    03A92310 8985 54FFFFFF MOV DWORD PTR SS:[EBP-AC],EAX
    03A92316 A1 A40D0704 MOV EAX,DWORD PTR DS:[4070DA4]
    03A9231B 3BC3 CMP EAX,EBX
    03A9231D 74 02 JE SHORT hw.03A92321
    03A9231F FFD0 CALL EAX
    03A92321 68 140E0704 PUSH hw.04070E14
    03A92326 E8 F5E3FFFF CALL hw.03A90720
    03A9232B A1 2C0E0704 MOV EAX,DWORD PTR DS:[4070E2C]
    03A92330 83C4 04 ADD ESP,4
    03A92333 3BC3 CMP EAX,EBX
    03A92335 74 0F JE SHORT hw.03A92346
    03A92337 50 PUSH EAX
    03A92338 E8 C02C0A00 CALL hw.03B34FFD
    03A9233D 83C4 04 ADD ESP,4
    03A92340 891D 2C0E0704 MOV DWORD PTR DS:[4070E2C],EBX
    03A92346 56 PUSH ESI
    03A92347 57 PUSH EDI
    03A92348 6A 74 PUSH 74
    03A9234A 53 PUSH EBX
    03A9234B 68 A00D0704 PUSH hw.04070DA0
    03A92350 E8 FB66FCFF CALL hw.03A58A50
    03A92355 B9 7A000000 MOV ECX,7A
    03A9235A 8DB5 70FDFFFF LEA ESI,DWORD PTR SS:[EBP-290]
    03A92360 BF B8A5B703 MOV EDI,hw.03B7A5B8
    03A92365 6A 14 PUSH 14
    03A92367 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
    03A92369 B9 2A000000 MOV ECX,2A
    03A9236E 8DB5 58FFFFFF LEA ESI,DWORD PTR SS:[EBP-A8]
    03A92374 BF 7844B603 MOV EDI,hw.03B64478
    03A92379 53 PUSH EBX
    03A9237A F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
    03A9237C 68 180E0704 PUSH hw.04070E18
    03A92381 E8 CA66FCFF CALL hw.03A58A50
    03A92386 83C4 18 ADD ESP,18
    03A92389 5F POP EDI
    03A9238A 5E POP ESI
    03A9238B 5B POP EBX
    03A9238C 8BE5 MOV ESP,EBP
    03A9238E 5D POP EBP
    03A9238F C3 RETN


    03A92374 BF 7844B603 MOV EDI,hw.03B64478 // this WAS the client table
    03A92360 BF B8A5B703 MOV EDI,hw.03B7A5B8 // engine func table


    Please make note that the RVA to this function is currently hw.dll + 0x61F80.

    The nullstub in question:

    Code:
    03A91F99 B8 501DA903 MOV EAX,hw.03A91D50
    hw.dll + 0x61D50

    Make sure to x-ref these two tables to catch more goodies.

    Comment


    • #3
      Alright so we got our indices and so on now what? Do spend all day fondling our private parts or do we fondle our private parts and stack currency to the roof? I recommend acquiring large sums of currency.

      This is a pre-emptive post to show I haven't forgotten and thus will be editted later today. Since I discussed the nullstub hooking we need to attach it to each engine function. Once having done that we can talk about how to actually get the pointers to engine, studio, and all the other goodies. Then we can think about cool stuff.

      Alright so, let's have a look at the trust engine functions.h file.

      This would be cdll_int.h.
      Code:
      typedef struct cl_enginefuncs_s
      {
      // sprite handlers
      HSPRITE ( *pfnSPR_Load ) ( const char *szPicName );
      int ( *pfnSPR_Frames ) ( HSPRITE hPic );
      int ( *pfnSPR_Height ) ( HSPRITE hPic, int frame );
      int ( *pfnSPR_Width ) ( HSPRITE hPic, int frame );
      void ( *pfnSPR_Set ) ( HSPRITE hPic, int r, int g, int b );
      void ( *pfnSPR_Draw ) ( int frame, int x, int y, const wrect_t *prc );
      void ( *pfnSPR_DrawHoles ) ( int frame, int x, int y, const wrect_t *prc );
      void ( *pfnSPR_DrawAdditive ) ( int frame, int x, int y, const wrect_t *prc );
      void ( *pfnSPR_EnableScissor ) ( int x, int y, int width, int height );
      void ( *pfnSPR_DisableScissor ) ( void );
      client_sprite_t *( *pfnSPR_GetList ) ( char *psz, int *piCount );
      
      // screen handlers
      void ( *pfnFillRGBA ) ( int x, int y, int width, int height, int r, int g, int b, int a );
      int ( *pfnGetScreenInfo ) ( SCREENINFO *pscrinfo );
      void ( *pfnSetCrosshair ) ( HSPRITE hspr, wrect_t rc, int r, int g, int b );
      
      // cvar handlers
      struct cvar_s *( *pfnRegisterVariable ) ( char *szName, char *szValue, int flags );
      float ( *pfnGetCvarFloat ) ( char *szName );
      char* ( *pfnGetCvarString ) ( char *szName );
      
      // command handlers
      int ( *pfnAddCommand ) ( char *cmd_name, void (*function)(void) );
      int ( *pfnHookUserMsg ) ( char *szMsgName, pfnUserMsgHook pfn );
      int ( *pfnServerCmd ) ( char *szCmdString );
      int ( *pfnClientCmd ) ( char *szCmdString );
      
      void ( *pfnGetPlayerInfo ) ( int ent_num, hud_player_info_t *pinfo );
      
      // sound handlers
      void ( *pfnPlaySoundByName ) ( char *szSound, float volume );
      void ( *pfnPlaySoundByIndex ) ( int iSound, float volume );
      
      // vector helpers
      void ( *pfnAngleVectors ) ( const float * vecAngles, float * forward, float * right, float * up );
      
      // text message system
      client_textmessage_t *( *pfnTextMessageGet ) ( const char *pName );
      int ( *pfnDrawCharacter ) ( int x, int y, int number, int r, int g, int b );
      int ( *pfnDrawConsoleString ) ( int x, int y, char *string );
      void ( *pfnDrawSetTextColor ) ( float r, float g, float b );
      void ( *pfnDrawConsoleStringLen )( const char *string, int *length, int *height );
      
      void ( *pfnConsolePrint ) ( const char *string );
      void ( *pfnCenterPrint ) ( const char *string );
      
      
      // Added for user input processing
      int ( *GetWindowCenterX ) ( void );
      int ( *GetWindowCenterY ) ( void );
      void ( *GetViewAngles ) ( float * );
      void ( *SetViewAngles ) ( float * );
      int ( *GetMaxClients ) ( void );
      void ( *Cvar_SetValue ) ( char *cvar, float value );
      
      int (*Cmd_Argc) (void);
      char *( *Cmd_Argv ) ( int arg );
      void ( *Con_Printf ) ( char *fmt, ... );
      void ( *Con_DPrintf ) ( char *fmt, ... );
      void ( *Con_NPrintf ) ( int pos, char *fmt, ... );
      void ( *Con_NXPrintf ) ( struct con_nprint_s *info, char *fmt, ... );
      
      const char *( *PhysInfo_ValueForKey ) ( const char *key );
      const char *( *ServerInfo_ValueForKey )( const char *key );
      float ( *GetClientMaxspeed ) ( void );
      int ( *CheckParm ) ( char *parm, char **ppnext );
      void ( *Key_Event ) ( int key, int down );
      void ( *GetMousePosition ) ( int *mx, int *my );
      int ( *IsNoClipping ) ( void );
      
      struct cl_entity_s *( *GetLocalPlayer ) ( void );
      struct cl_entity_s *( *GetViewModel ) ( void );
      struct cl_entity_s *( *GetEntityByIndex ) ( int idx );
      
      float ( *GetClientTime ) ( void );
      void ( *V_CalcShake ) ( void );
      void ( *V_ApplyShake ) ( float *origin, float *angles, float factor );
      
      int ( *PM_PointContents ) ( float *point, int *truecontents );
      int ( *PM_WaterEntity ) ( float *p );
      struct pmtrace_s *( *PM_TraceLine ) ( float *start, float *end, int flags, int usehull, int ignore_pe );
      
      struct model_s *( *CL_LoadModel ) ( const char *modelname, int *index );
      int ( *CL_CreateVisibleEntity ) ( int type, struct cl_entity_s *ent );
      
      const struct model_s * ( *GetSpritePointer ) ( HSPRITE hSprite );
      void ( *pfnPlaySoundByNameAtLocation ) ( char *szSound, float volume, float *origin );
      
      unsigned short ( *pfnPrecacheEvent ) ( int type, const char* psz );
      void ( *pfnPlaybackEvent ) ( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );
      void ( *pfnWeaponAnim ) ( int iAnim, int body );
      float ( *pfnRandomFloat ) ( float flLow, float flHigh );
      long ( *pfnRandomLong ) ( long lLow, long lHigh );
      void ( *pfnHookEvent ) ( char *name, void ( *pfnEvent )( struct event_args_s *args ) );
      int (*Con_IsVisible) ();
      const char *( *pfnGetGameDirectory ) ( void );
      struct cvar_s *( *pfnGetCvarPointer ) ( const char *szName );
      const char *( *Key_LookupBinding ) ( const char *pBinding );
      const char *( *pfnGetLevelName ) ( void );
      void ( *pfnGetScreenFade ) ( struct screenfade_s *fade );
      void ( *pfnSetScreenFade ) ( struct screenfade_s *fade );
      void *( *VGui_GetPanel ) ( );
      void ( *VGui_ViewportPaintBackground ) (int extents[4]);
      
      byte* (*COM_LoadFile) ( char *path, int usehunk, int *pLength );
      char* (*COM_ParseFile) ( char *data, char *token );
      void (*COM_FreeFile) ( void *buffer );
      
      struct triangleapi_s *pTriAPI;
      struct efx_api_s *pEfxAPI;
      struct event_api_s *pEventAPI;
      struct demo_api_s *pDemoAPI;
      struct net_api_s *pNetAPI;
      struct IVoiceTweak_s *pVoiceTweak;
      
      // returns 1 if the client is a spectator only (connected to a proxy), 0 otherwise or 2 if in dev_overview mode
      int ( *IsSpectateOnly ) ( void );
      struct model_s *( *LoadMapSprite ) ( const char *filename );
      
      // file search functions
      void ( *COM_AddAppDirectoryToSearchPath ) ( const char *pszBaseDir, const char *appName );
      int ( *COM_ExpandFilename) ( const char *fileName, char *nameOutBuffer, int nameOutBufferSize );
      
      // User info
      // playerNum is in the range (1, MaxClients)
      // returns NULL if player doesn't exit
      // returns "" if no value is set
      const char *( *PlayerInfo_ValueForKey )( int playerNum, const char *key );
      void ( *PlayerInfo_SetValueForKey )( const char *key, const char *value );
      
      // Gets a unique ID for the specified player. This is the same even if you see the player on a different server.
      // iPlayer is an entity index, so client 0 would use iPlayer=1.
      // Returns false if there is no player on the server in the specified slot.
      qboolean (*GetPlayerUniqueID)(int iPlayer, char playerID[16]);
      
      // TrackerID access
      int (*GetTrackerIDForPlayer)(int playerSlot);
      int (*GetPlayerForTrackerID)(int trackerID);
      
      // Same as pfnServerCmd, but the message goes in the unreliable stream so it can't clog the net stream
      // (but it might not get there).
      int ( *pfnServerCmdUnreliable )( char *szCmdString );
      
      void ( *pfnGetMousePos )( struct tagPOINT *ppt );
      void ( *pfnSetMousePos )( int x, int y );
      void ( *pfnSetMouseEnable )( qboolean fEnable );
      } cl_enginefunc_t;

      You'll note there's tons of goodies for us to hook or call.

      Some of my favs were:

      Code:
      Code:
      int ( *pfnAddCommand ) ( char *cmd_name, void (*function)(void) );
      int ( *pfnHookUserMsg ) ( char *szMsgName, pfnUserMsgHook pfn );
      AddCommand added the command to a linked list of stuff. It was trivial to walk this list and hook the appropriate command to block slowhacks.

      UserMsg is also a linked list and full of useful goodies, like teaminfo, and information on deaths for other players.

      The event api was used in prediction if I recall correctly and one of the expeditious ways to hook CreateMove quietly.

      Code:
      Code:
      int DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion )
      {
      gEngfuncs = *pEnginefuncs;
      
      if (iVersion != CLDLL_INTERFACE_VERSION)
      return 0;
      
      memcpy(&gEngfuncs, pEnginefuncs, sizeof(cl_enginefunc_t));
      
      EV_HookEvents();
      
      return 1;
      }
      Oh my GOD! Yeah it's that damn easy. Sig that puppy and laugh all day it seems. Meaning x-ref where initialize is called and you win.

      Ditto for studio....

      Code:
      Code:
      #define DLLEXPORT __declspec( dllexport )
      extern "C" int DLLEXPORT HUD_GetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio )
      {
      if ( version != STUDIO_INTERFACE_VERSION )
      return 0;
      
      // Point the engine to our callbacks
      *ppinterface = &studio;
      
      // Copy in engine helper functions
      memcpy( &IEngineStudio, pstudio, sizeof( IEngineStudio ) );
      
      // Initialize local variables, etc.
      R_StudioInit();
      
      // Success
      return 1;
      }
      So by now you should have full access to all engine functions and studio functions with a working client hook if you did the hooking, nullstub hooking is more difficult but I promise I will discuss it. It's just walking the stack and looking for a return. Usually 2 stackframes in most cases or all.

      Comment


      • #4
        Anyway on topic, I'll cover nullstub hooking and begin building a base framework and a github repo for everything. Stay tuned.

        So next couple of days, nullstub hooking, event hooking, usermsg hooking, cmd hooking. Important topics, most of them are linked list modification.

        First we'll cover command hooking. Recognize that pfnAddCommand is the 17th entry in the engine functions. Next realize that each command entry is 16 bytes large.

        Code:
        typedef struct HL_Command_s
        {
        HL_Command_s* m_pNext;
        char* m_pszName;
        void* m_pFunction; // void* or intptr_t suffices for our purposes
        intptr_t m_iUnknown; // this is not necessary, we could also replace it with char m_Padding[4]; as well, it's just 0, so maybe it's a version indicator?
        }HL_Command_t;
        Ok so we need the global ptr to all the commands, easy to find.
        03D27A70 55 PUSH EBP
        03D27A71 8BEC MOV EBP,ESP
        03D27A73 56 PUSH ESI
        03D27A74 57 PUSH EDI
        03D27A75 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]
        03D27A78 57 PUSH EDI
        03D27A79 E8 425E0000 CALL hw.03D2D8C0
        03D27A7E 8A08 MOV CL,BYTE PTR DS:[EAX]
        03D27A80 83C4 04 ADD ESP,4
        03D27A83 84C9 TEST CL,CL
        03D27A85 74 12 JE SHORT hw.03D27A99
        03D27A87 57 PUSH EDI
        03D27A88 68 DCB6E303 PUSH hw.03E3B6DC ; ASCII "Cmd_AddCommand: %s already defined as a var
        "
        03D27A8D E8 EE450000 CALL hw.03D2C080
        03D27A92 83C4 08 ADD ESP,8
        03D27A95 5F POP EDI
        03D27A96 5E POP ESI
        03D27A97 5D POP EBP
        03D27A98 C3 RETN
        03D27A99 8B35 5008FE03 MOV ESI,DWORD PTR DS:[3FE0850]
        03D27A9F 85F6 TEST ESI,ESI
        03D27AA1 74 17 JE SHORT hw.03D27ABA
        03D27AA3 8B46 04 MOV EAX,DWORD PTR DS:[ESI+4]
        03D27AA6 50 PUSH EAX
        03D27AA7 57 PUSH EDI
        03D27AA8 E8 83110000 CALL hw.03D28C30
        03D27AAD 83C4 08 ADD ESP,8
        03D27AB0 85C0 TEST EAX,EAX
        03D27AB2 74 23 JE SHORT hw.03D27AD7
        03D27AB4 8B36 MOV ESI,DWORD PTR DS:[ESI]
        03D27AB6 85F6 TEST ESI,ESI
        03D27AB8 ^75 E9 JNZ SHORT hw.03D27AA3
        03D27ABA 6A 10 PUSH 10
        03D27ABC E8 DFA10300 CALL hw.03D61CA0
        03D27AC1 8B4D 0C MOV ECX,DWORD PTR SS:[EBP+C]
        03D27AC4 83C4 04 ADD ESP,4
        03D27AC7 85C9 TEST ECX,ECX
        03D27AC9 8978 04 MOV DWORD PTR DS:[EAX+4],EDI
        03D27ACC 75 1B JNZ SHORT hw.03D27AE9
        03D27ACE C740 08 A07FD203 MOV DWORD PTR DS:[EAX+8],hw.03D27FA0
        03D27AD5 EB 15 JMP SHORT hw.03D27AEC
        03D27AD7 57 PUSH EDI
        03D27AD8 68 0CB7E303 PUSH hw.03E3B70C ; ASCII "Cmd_AddCommand: %s already defined
        "
        03D27ADD E8 9E450000 CALL hw.03D2C080
        03D27AE2 83C4 08 ADD ESP,8
        03D27AE5 5F POP EDI
        03D27AE6 5E POP ESI
        03D27AE7 5D POP EBP
        03D27AE8 C3 RETN
        03D27AE9 8948 08 MOV DWORD PTR DS:[EAX+8],ECX
        03D27AEC 8B4D 10 MOV ECX,DWORD PTR SS:[EBP+10]
        03D27AEF 8B15 5008FE03 MOV EDX,DWORD PTR DS:[3FE0850]
        03D27AF5 5F POP EDI
        03D27AF6 8948 0C MOV DWORD PTR DS:[EAX+C],ECX
        03D27AF9 8910 MOV DWORD PTR DS:[EAX],EDX
        03D27AFB A3 5008FE03 MOV DWORD PTR DS:[3FE0850],EAX
        03D27B00 5E POP ESI
        03D27B01 5D POP EBP
        03D27B02 C3 RETN

        hw.dll + 0x2E0850, or 0x3FE0850, sig and whatever.

        So to recap.

        Code:
        Code:
        HL_Command_t* pCommand = ( HL_Command_t* )dwHWBase + 0x2E0850;
        
        do
        {
        if ( !stricmp ( pCommand->m_pszName, "command_to_hook" ) )
        {
        // replace and store
        }
        
        pCommand = pCommand->m_pNext;
        } while ( pCommand != NULL );
        Easy wasn't it? Same type of procedure for event hooking and usermsg hooking.

        Usermsg is the 18th entry in the engine functions list. You'll note usermsgs are larger than their command counterparts ( obviously ), so we have to look at how it's setup.

        03D1A3A0 55 PUSH EBP
        03D1A3A1 8BEC MOV EBP,ESP
        03D1A3A3 53 PUSH EBX
        03D1A3A4 8B5D 0C MOV EBX,DWORD PTR SS:[EBP+C]
        03D1A3A7 56 PUSH ESI
        03D1A3A8 8B35 6C9DE603 MOV ESI,DWORD PTR DS:[3E69D6C]
        03D1A3AE 57 PUSH EDI
        03D1A3AF 33FF XOR EDI,EDI
        03D1A3B1 85F6 TEST ESI,ESI
        03D1A3B3 74 24 JE SHORT hw.03D1A3D9
        03D1A3B5 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8]
        03D1A3B8 8D46 08 LEA EAX,DWORD PTR DS:[ESI+8]
        03D1A3BB 50 PUSH EAX
        03D1A3BC 51 PUSH ECX
        03D1A3BD E8 6EE90000 CALL hw.03D28D30
        03D1A3C2 83C4 08 ADD ESP,8
        03D1A3C5 85C0 TEST EAX,EAX
        03D1A3C7 75 09 JNZ SHORT hw.03D1A3D2
        03D1A3C9 8B46 1C MOV EAX,DWORD PTR DS:[ESI+1C]
        03D1A3CC 8BFE MOV EDI,ESI
        03D1A3CE 3BC3 CMP EAX,EBX
        03D1A3D0 74 22 JE SHORT hw.03D1A3F4
        03D1A3D2 8B76 18 MOV ESI,DWORD PTR DS:[ESI+18]
        03D1A3D5 85F6 TEST ESI,ESI
        03D1A3D7 ^75 DC JNZ SHORT hw.03D1A3B5
        03D1A3D9 6A 20 PUSH 20
        03D1A3DB E8 C0780400 CALL hw.03D61CA0
        03D1A3E0 83C4 04 ADD ESP,4
        03D1A3E3 8BF0 MOV ESI,EAX
        03D1A3E5 85FF TEST EDI,EDI
        03D1A3E7 74 13 JE SHORT hw.03D1A3FC
        03D1A3E9 6A 20 PUSH 20
        03D1A3EB 57 PUSH EDI
        03D1A3EC 56 PUSH ESI
        03D1A3ED E8 BEE60000 CALL hw.03D28AB0
        03D1A3F2 EB 1B JMP SHORT hw.03D1A40F
        03D1A3F4 8B46 1C MOV EAX,DWORD PTR DS:[ESI+1C]
        03D1A3F7 5F POP EDI
        03D1A3F8 5E POP ESI
        03D1A3F9 5B POP EBX
        03D1A3FA 5D POP EBP
        03D1A3FB C3 RETN
        03D1A3FC 8B55 08 MOV EDX,DWORD PTR SS:[EBP+8]
        03D1A3FF 6A 0F PUSH 0F
        03D1A401 8D46 08 LEA EAX,DWORD PTR DS:[ESI+8]
        03D1A404 52 PUSH EDX
        03D1A405 50 PUSH EAX
        03D1A406 E8 75E70000 CALL hw.03D28B80
        03D1A40B C646 17 00 MOV BYTE PTR DS:[ESI+17],0
        03D1A40F 8B0D 6C9DE603 MOV ECX,DWORD PTR DS:[3E69D6C]
        03D1A415 83C4 0C ADD ESP,0C
        03D1A418 895E 1C MOV DWORD PTR DS:[ESI+1C],EBX
        03D1A41B 894E 18 MOV DWORD PTR DS:[ESI+18],ECX
        03D1A41E 8935 6C9DE603 MOV DWORD PTR DS:[3E69D6C],ESI
        03D1A424 5F POP EDI
        03D1A425 5E POP ESI
        03D1A426 33C0 XOR EAX,EAX
        03D1A428 5B POP EBX
        03D1A429 5D POP EBP
        03D1A42A C3 RETN
        From what I can see immediately the size of a usermsg entry is 0x1C, or 28 bytes. What we're interested in is the m_pFunction, m_pNext and the string to find the msg we want to hook. Nothing else.

        Code:
        0B281F00 00 00 00 00 00 00 00 00 ........
        0B281F08 52 65 71 53 74 61 74 65 ReqState
        0B281F10 00 00 00 00 00 00 00 00 ........
        0B281F18 D8 1E 28 0B 10 CD E3 0B Ø(Íã
        Seems the string is imbedded into the usermsg entry itself, ok. That makes it easier since we know that the string starts at + 0x8.

        Code:
        Code:
        typedef struct HL_UserMsg_s
        {
        char m_Padding[8];
        char m_szUserMsg[15];
        char m_Unknown; // version of some kind?
        HL_UserMsg_s* m_pNext;
        void* m_pFunction;
        }HL_UserMsg_t;
        Ditto for procedure to hook as command, easy wasn't it?

        Code:
        Code:
        HL_UserMsg_t* pMessage = ( HL_UserMsg_t* )dwHW + 0x169D6C;
        Event hooking, ayy... Same type of procedure. I am not going to worry about details here too much.

        Code:
        03D1EA70 55 PUSH EBP
        03D1EA71 8BEC MOV EBP,ESP
        03D1EA73 8D45 0C LEA EAX,DWORD PTR SS:[EBP+C]
        03D1EA76 56 PUSH ESI
        03D1EA77 8D4D 08 LEA ECX,DWORD PTR SS:[EBP+8]
        03D1EA7A 50 PUSH EAX
        03D1EA7B 51 PUSH ECX
        03D1EA7C FF15 CCA6E403 CALL DWORD PTR DS:[3E4A6CC] ; hw.03D61D50
        03D1EA82 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
        03D1EA85 83C4 08 ADD ESP,8
        03D1EA88 85C0 TEST EAX,EAX
        03D1EA8A 74 70 JE SHORT hw.03D1EAFC
        03D1EA8C 8038 00 CMP BYTE PTR DS:[EAX],0
        03D1EA8F 74 6B JE SHORT hw.03D1EAFC
        03D1EA91 8B4D 0C MOV ECX,DWORD PTR SS:[EBP+C]
        03D1EA94 85C9 TEST ECX,ECX
        03D1EA96 75 10 JNZ SHORT hw.03D1EAA8
        03D1EA98 68 74A8E303 PUSH hw.03E3A874 ; ASCII "CL_HookEvent: Must provide an event hook callback
        "
        03D1EA9D E8 DED50000 CALL hw.03D2C080
        03D1EAA2 83C4 04 ADD ESP,4
        03D1EAA5 5E POP ESI
        03D1EAA6 5D POP EBP
        03D1EAA7 C3 RETN
        03D1EAA8 50 PUSH EAX
        03D1EAA9 E8 82FFFFFF CALL hw.03D1EA30
        03D1EAAE 8BF0 MOV ESI,EAX
        03D1EAB0 83C4 04 ADD ESP,4
        03D1EAB3 85F6 TEST ESI,ESI
        03D1EAB5 74 16 JE SHORT hw.03D1EACD
        03D1EAB7 68 A8A8E303 PUSH hw.03E3A8A8 ; ASCII "CL_HookEvent: Called on existing hook, updating event hook
        "
        03D1EABC E8 DFD60000 CALL hw.03D2C1A0
        03D1EAC1 8B55 0C MOV EDX,DWORD PTR SS:[EBP+C]
        03D1EAC4 83C4 04 ADD ESP,4
        03D1EAC7 8956 08 MOV DWORD PTR DS:[ESI+8],EDX
        03D1EACA 5E POP ESI
        03D1EACB 5D POP EBP
        03D1EACC C3 RETN
        03D1EACD 6A 0C PUSH 0C
        03D1EACF E8 CC310400 CALL hw.03D61CA0
        03D1EAD4 8BF0 MOV ESI,EAX
        03D1EAD6 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
        03D1EAD9 50 PUSH EAX
        03D1EADA E8 31320400 CALL hw.03D61D10
        03D1EADF 8B15 889DE603 MOV EDX,DWORD PTR DS:[3E69D88]
        03D1EAE5 8946 04 MOV DWORD PTR DS:[ESI+4],EAX
        03D1EAE8 8B4D 0C MOV ECX,DWORD PTR SS:[EBP+C]
        03D1EAEB 83C4 08 ADD ESP,8
        03D1EAEE 894E 08 MOV DWORD PTR DS:[ESI+8],ECX
        03D1EAF1 8916 MOV DWORD PTR DS:[ESI],EDX
        03D1EAF3 8935 889DE603 MOV DWORD PTR DS:[3E69D88],ESI
        03D1EAF9 5E POP ESI
        03D1EAFA 5D POP EBP
        03D1EAFB C3 RETN
        03D1EAFC 68 E8A8E303 PUSH hw.03E3A8E8 ; ASCII "CL_HookEvent: Must provide a valid event name
        "
        03D1EB01 E8 7AD50000 CALL hw.03D2C080
        03D1EB06 83C4 04 ADD ESP,4
        03D1EB09 5E POP ESI
        03D1EB0A 5D POP EBP
        03D1EB0B C3 RETN
        Code:
        05218F18 00 8F 21 05 D0 F4 27 05 .!Ðô'
        05218F20 80 A0 DD 0B 00 00 00 00 €[censored]Ý....
        m_pNext;
        + 0x4 m_pszName
        + 0x8 is the pFunction.
        So.

        Code:
        Code:
        typedef HL_Event_s
        {
        HL_Event_s* m_pNext;
        char* m_pszName;
        void* m_pFunction;
        char m_Padding[4];
        intptr_t m_iUnknown; // checksum(?)
        intptr_t m_iUnknown2; // event version(?)
        
        }HL_Event_t;
        The padding in this case is not strictly necessary. Nor is the other portion of the event since the m_pNext and everything we need is at the start.

        Code:
        Code:
        HL_Event_t* pEvent = ( HL_Event_t* )dwHW + 0x169D88;
        Now I covered nullstub hooking somewhat earlier, but in truth it's just the same as if we were doing anything else.

        Code:
        Code:
        intptr_t* pNullstub = ( intptr_t* )dwHW + 0x14A5B8;
        Code:
        Code:
        memcpy ( pNullstub, &mytable, 122 );
        OR

        Code:
        Code:
        pNullstub[index] = &Function; // OR pNullstub[index] = ( intptr_t )Function, ( unsigned long )Function... so forth
        Remember you're using a jumpgate to search for the return address for each function you intend to hook, and to check further up the frame to see where you were called from so you can either overwrite the return address or do nothing as appropriate based on the function you're hooking.

        Any further questions, I'll be happy to respond as long as they are relevant.

        Comment


        • #5
          So we've reached an important landmark, everything we need to hook is known to us. Now what?

          Well, we need to begin implementing client features, this post is a simple post to describe what we will need in detail from the client functions.

          HUD_Redraw
          CL_CreateMove
          HUD_PostRunCmd
          HUD_AddEntity
          V_CalcRefdef
          HUD_PlayerMove

          These are the core client functions we will need to do our dirty work.

          HUD_Redraw will be used for our ESP.
          CL_CreateMove is for all aimbot, movement, triggerbot, and other stuff
          HUD_PostRunCmd is for nospread/prediction, and to provide us information for auto pistol
          HUD_AddEntity does exactly as described
          V_CalcRefdef for getting punchangles and zeroing them, and applying aimbot angles if noviewchange is not on
          HUD_PlayerMove for local player prediction really important

          Event hooks will be used to show the compensation applied by nospread/norecoil, but bare in mind with 1.6 punchangles are finnicky

          I've covered some of the other topics, like shielders in another thread, that is simply using an intersection of planes to check, really easy.


          https://github.com/ValveSoftware/hal...ine/cdll_int.h


          // Dummy destination function for use when there's no security module
          extern void NullDst(void);


          0BB236EA B9 86000000 MOV ECX,86
          0BB236EF 83F8 07 CMP EAX,7
          0BB236F2 53 PUSH EBX
          0BB236F3 56 PUSH ESI
          0BB236F4 8BB424 14040000 MOV ESI,DWORD PTR SS:[ESP+414]
          0BB236FB 57 PUSH EDI
          0BB236FC BF 604CC00B MOV EDI,client.0BC04C60
          0BB23701 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
          https://bitbucket.org/cachemoney2014/goldsrc

          I've created a new repo to begin pushing stuff to. I won't promise steady commits or updates.

          Solving shielders? Simple plane check. How so?

          Code:
          bool linePlaneIntersection(Vector& contact, Vector ray, Vector rayOrigin,
          Vector normal, Vector coord) {
          // get d value
          float d = Dot(normal, coord);
          
          if (Dot(normal, ray) == 0) {
          return false; // No intersection, the line is parallel to the plane
          }
          
          // Compute the X value for the directed line ray intersecting the plane
          float x = (d - Dot(normal, rayOrigin)) / Dot(normal, ray);
          
          // output contact point
          *contact = rayOrigin + normalize(ray)*x; //Make sure your ray vector is normalized
          return true;
          }

          Granted as of right now this is useless to us as we don't have the surface normal to the shield hitbox.

          Turns out, this is not too difficult to solve for.
          https://math.stackexchange.com/quest...-of-a-triangle

          So to compute the normal, all we need to do is use the mins/maxs of the hitbox.

          Note there are better ways of doing this, but for the point of this post and indeed the hack, this will suffice for now.



          Comment

          Working...
          X