PDA

View Full Version : [Tutorial] Add libcod support for your cod version.



Mitch
25th December 2014, 17:06
Open your binary with IDA Pro decompiler. (google: ida 6.1 decompiler)

Search for "parameter count exceeds 256". Press F5 to get the pseudecode for this function.
Now search for the next match and also press F5.
We have got now 2 functions. One is for the methods and one is for the functions.

We need to find something like this: (edit: double click the function first and then redo F5 on the original function)

v7 = sub_50D280((const char **)&v16, (int)&v14);

It should be in the first else. For function it would be the first function. And for methods it is the last one (it has a few ifs).

Now you need to find where this function is called from. (go back to the view)

812

In main.cpp you need to add the call for method/function.

#if COD_VERSION == COD2_1_3
cracking_hook_call(0x46E7BF, (int)Scr_GetCustomFunction);
cracking_hook_call(0x46EA03, (int)Scr_GetCustomMethod);
#endif

And you need to add the address of the function itself to gsc.cpp.


#if COD_VERSION == COD2_1_3
Scr_GetFunction_t Scr_GetFunction = (Scr_GetFunction_t)0x50D280;
Scr_GetMethod_t Scr_GetMethod = (Scr_GetMethod_t)0x50D310;
#else


Search for 'setcvar' in IDA. (without '')


.rdata:005B9750 aSetcvar db 'setcvar',0

Copy the address and split it by each 2 characters. Now invert the values.

So change 5B 97 50 to 50 97 5B. Now open the binary with a text editor. Now search for the hex value '50 97 5B'.
Now in IDA jump to the offset that your editor returns. In this case it is '1D9294'.
Now press D 3 times. Now go the next line and also press D 3 times.

Now you should see this:


.data:005D9294 dd offset aSetcvar ; "setcvar"
.data:005D9298 dd offset sub_5050B0

Double click on sub_5050B0.



if ( v0 )
{
v1 = dword_DF8D80 + 8 * v0 + 4; // stackGetParamString
v16 = dword_DF8D80 + 8 * v0 + 4;
}
else
{
v16 = 0;
v1 = 0;
}
if ( (unsigned int)dword_F4B91C <= 1 ) // getNumberOfParams
{
v3 = sub_44A990("parameter %d does not exist", 2);
if ( !*(_DWORD *)dword_F08F98 )
*(_DWORD *)dword_F08F98 = v3;
sub_47D5A0(); // (probably pushes undefined)
}
else
{
if ( *(_DWORD *)(dword_F4B910 - 4) == 3 ) // getStack
{
sub_504700(dword_F4B91C - 1, (unsigned int)"Dvar Value", &v17, 1024);


If you decompile one function below 'setcvar' you get the function 'gettime'.


int __cdecl sub_483580(int value) // (see stackPush function)
{
int result; // eax@3

sub_47D630(); // stackNew
if ( dword_F4B910 == dword_F4B904 ) // stackCheck
sub_4324C0(1, &byte_5B01D0); // stackCheck
result = dword_F4B910 + 8;
dword_F4B910 = result; // getStack
++dword_F4B918; // getNumberOfReturnValues
*(_DWORD *)(result + 4) = 6; // 6 = STACK_INT
*(_DWORD *)dword_F4B910 = value; // getStack
return result;
}

This function is stackPushInt.

For other address you need to decompile other function for the right parameter/return types.
(in linux you have almost none usercalls. You can't use these addresses. You need to recreate them.)