挂钩usercall功能? [英] Hooking usercall function?
问题描述
我有一个虚拟机,该上VM_Create传递函数(systemCalls)到虚拟机。地址
所以,我勾VM_Create和窃取系统调用地址,把它变成一个备份函数指针,而我的修正systemCalls函数的地址传递给原来的VM_Create,从中我可以改变的参数,添加或删除通话,然后调用备份的系统调用功能。这种运作良好,直到比赛的一个新版本。
我相信已经找到了问题:
这是未修改systemCalls函数的开头:
使用intptr_t CL_CgameSystemCalls(使用intptr_t *参数){ 开关(参数[0]){ 案例CG_PRINT:
Com_Printf(%S,(为const char *)VMA(1));
返回0; 案例CG_ERROR:
Com_Error(ERR_DROP,%S,(为const char *)VMA(1));
返回0;
这是我的系统调用体改功能:
使用intptr_t modified_CL_CgameSystemCalls(使用intptr_t *参数)
{
开关(*参数)
{
案例CG_GETSNAPSHOT: mysnap = mysnap;
mynextSnap =(snapshot_t *)(CG_QVM2NATIVE(参数[2]));
mysnap = mynextSnap; RETVAL = original_CL_CgameSystemCalls(参数);
突破;
问题是调用从修改一个原有的功能:
使用intptr_t modified_CL_CgameSystemCalls(使用intptr_t *参数)
{
RETVAL = original_CL_CgameSystemCalls(参数);
返回RETVAL;
}
已经失败。
你可以从拆卸的伪code看到,CL_CgameSystemCalls的新定义似乎是:
字符__usercall sub_4017B0<&人GT;(INT A1中EBX>中INT A2)
这意味着他们加入__usercall属性,并通过将第一个参数到寄存器EBX,如果我间preT反编译权变更的功能。
现在我的问题:
我如何可以检索* ARGS(参数[0])到一个变量?
和我怎么能叫从修改一个未经修改的功能,现在使用__usercall?
这是usercall systemcalls的拆卸:
的.text:004017B0; ===============子程序================================== =====
的.text:004017B0
的.text:004017B0
的.text:004017B0 sub_4017B0 PROC附近; DATA XREF:sub_402670 + 5CO
的.text:004017B0
的.text:004017B0 var_18 = DWORD PTR -18h
的.text:004017B0 VAR_4 = DWORD PTR -4
的.text:004017B0 ARG_0 = DWORD PTR 4
的.text:004017B0
的.text:004017B0;函数组块AT的.text:00401430 SIZE 00000026 BYTES
的.text:004017B0;函数组块AT的.text:00401459 SIZE 00000013 BYTES
的.text:004017B0;函数组块AT的.text:00410E90 SIZE 00000006 BYTES
的.text:004017B0;函数组块AT的.text:00412AC0 SIZE 00000006 BYTES
的.text:004017B0
的.text:004017B0推ESI
的.text:004017B1 MOV ESI,[ESP + 0CH + VAR_4]
的.text:004017B5 MOV EAX,[ESI]
的.text:004017B7 CMP EAX,73H;切换116案件
的.text:004017BA推EDI
的.text:004017BB JA loc_402486;默认
的.text:004017BB;跳转表004017C1案件21,90-99,109,110
的.text:004017C1 JMP DS:off_40249C [EAX * 4];开关跳
的.text:004017C8
的.text:004017C8 loc_4017C8:; DATA XREF:的.text:off_40249Co
的.text:004017C8 MOV EAX,[ESI + 4];跳转表004017C1情况下0
的.text:004017CB推EAX
的.text:004017CC打电话VM_ArgPtr
的.text:004017D1 EAX推;烧焦
的.text:004017D2推抵消aS_5; %S
的.text:004017D7通话Com_Printf
的.text:004017DC加ESP,0CH
的.text:004017DF流行EDI
的.text:004017E0 XOR EAX,EAX
的.text:004017E2流行ESI
的.text:004017E3 RETN
的.text:004017E4; -------------------------------------------------- -------------------------
的.text:004017E4
的.text:004017E4 loc_4017E4:; code XREF:sub_4017B0 + 11J
的.text:004017E4; DATA XREF:的.text:off_40249Co
的.text:004017E4 MOV ECX,[ESI + 4];跳转表004017C1案例1
的.text:004017E7推ECX
的.text:004017E8打电话VM_ArgPtr
的.text:004017ED推EAX;烧焦
的.text:004017EE推抵消aS_5; %S
的.text:004017F3推1; INT
的.text:004017F5通话Com_Error
的.text:004017F5; -------------------------------------------------- ------------
这是从hexrays反编译器产生的伪code:
字符__usercall sub_4017B0<&人GT;(INT A1中EBX>中INT A2)
{
INT V2; // @ ST34_4 1
焦炭结果; // @人2
INT V4; // @ ST34_4 2
INT V5; // @ EAX 2
INT V6; // @ ST34_4 3
INT V7; // @ EAX 3
INT V8; // @ ST34_4 5
INT V9; // @ ST24_4 5
INT V10; // @ ST20_4 5
INT V11; // @ ST1C_4 5
INT V12; // @ EAX 5
INT V13; // @ ST34_4 6
INT V14; // @ EAX 6
INT V15; // @ ST34_4 7
INT V16; // @ ST24_4 7
INT V17; // @ EAX 7
INT V18; // @ ST34_4 8
符号int V19; // @ ST24_4 8
INT V20; // @ ST20_4 8
INT V21; // @ EAX 8
INT V22; // @ ST34_4 10
符号int V23; // @ ST24_4 10
INT V24; // @ EAX 10
INT V25; // @ ST34_4 11
符号int V26; // @ ST24_4 11
INT V27; // @ EAX 11
INT V28; // @ ST34_4 12
INT V29; // @ ST24_4 12
INT V30; // @ ST20_4 12
INT V31; // @ EAX 12
INT V32; // @ ST34_4 13
INT V33; // @ ST24_4 13
INT V34; // @ ST20_4 13
INT V35; // @ EAX 13
INT V36; // @ ST34_4 14
INT V37; // @ ST24_4 14
为size_t V38; // @ ST20_4 14
INT V39; // @ EAX 14
INT V40; // @ ST34_4 15
INT V41; // @ ST34_4 16
INT V42; // @ ST34_4 17
INT V43; // @ EAX 17
INT V44; // @ ST34_4 18
INT V45; // @ EAX 18
INT V46; // @ ST34_4 19
INT V47; // @ EAX 19
INT V48; // @ ST34_4 20
INT V49; // @ EAX 20
INT V50; // @ ST34_4 22
INT V51; // @ EAX 22
无效* V52; // @ ECX 22
INT V53; // @ ST34_4 24
INT V54; // @ ST20_4 24
INT V55; // @ EAX 24
INT V56; // @ ST34_4 25
INT V57; // @ ST20_4 25
INT V58; // @ EAX 25
INT V59; // @ ST34_4 26
符号int V60; // @ ST24_4 26
INT V61; // @ EAX 26
INT V62; // @ ST34_4 27
INT V63; // @ ST24_4 27
INT V64; // @ ST20_4 27
符号int魔V65; // @ ST1C_4 27
INT V66; // @ EAX 27
INT V67; // @ ST34_4 28
INT V68; // @ EAX 29
INT V69; // @ ST34_4 30
INT V70; // @ ST34_4 32
INT V71; // @ ST20_4 32
INT V72; // @ ST1C_4 32
INT V73; // @ ST18_4 32
符号int V74; // @ ST14_4 32
INT V75; // @ ST10_4 32
INT V76; // @ ST0C_4 32
INT V77; // @ ST08_4 32
INT V78; // @ ST04_4 32
INT V79; // @ EAX 32
INT V80; // @ ST34_4 34
INT V81; // @ ST24_4 34
INT V82; // @ ST20_4 34
INT V83; // @ ST1C_4 34
INT V84; // @ ST18_4 34
INT V85; // @ ST14_4 34
INT V86; // @ EAX 34
INT V87; // @ ST34_4 35
INT V88; // @ ST24_4 35
INT V89; // @ ST20_4 35
INT V90; // @ ST1C_4 35
INT V91; // @ EAX 35
INT V92; // @ ST34_4 36
INT V93; // @ ST34_4 37
INT V94; // @ ST34_4 38
INT V95; // @ ST24_4 38
INT V96; // @ ST20_4 38
INT V97; // @ EAX 38
INT V98; // @ ST34_4 39
INT V99; // @ ST24_4 39
INT V100; // @ ST20_4 39
INT V101; // @ EAX 39
INT V102; // @ ST34_4 40
INT V103; // @ ST34_4 41
INT V104; // @ EAX 41
INT V105; // @ ST34_4 42
INT V106; // @ ST20_4 42
INT V107; // @ EAX 42
INT V108; // @ ST34_4 43
INT V109; // @ EAX 43
INT V110; // @ ST34_4 44
INT V111; // @ ST24_4 44
INT V112; // @ EAX 44
INT V113; // @ ST34_4 45
INT V114; // @ EAX 45
INT V115; // @ ST34_4 46
INT v116; // @ EAX 46
INT v117; // @ ST34_4 47
INT V118; // @ ST34_4 48
INT v119; // @ ST34_4 49
INT V120; // @ ST34_4 50
INT V121; // @ ST24_4 50
INT V122; // @ ST20_4 50
INT V123; // @ EAX 50
INT v124; // @ ST34_4 52
INT V125; // @ EAX 52
INT v126; // @ ST34_4 53
INT V127; // @ EAX 53
INT V128; // @ ST34_4 54
INT V129; // @ ST24_4 54
INT V130; // @ EAX 54
INT V131; // @ ST34_4 55
INT v132; // @ ST24_4 55
INT V133; // @ ST20_4 55
INT V134; // @ ST1C_4 55
INT v135; // @ EAX 55
INT v136; // @ ST34_4 56
漂浮v137; // @ ST24_4 56
漂浮v138; // @ ST20_4 56
漂浮v139; // @ ST1C_4 56
浮V140; // @ ST18_4 56
INT v141; // @ EAX 56
INT V142; // @ ST34_4 57
浮V143; // @ ST24_4 57
漂浮v144; // @ ST20_4 57
漂浮v145; // @ ST1C_4 57
漂浮v146; // @ ST18_4 57
INT V147; // @ EAX 57
INT v148; // @ ST34_4 58
INT v149; // @ EAX 58
INT V150; // @ ST34_4 59
INT v151; // @ EAX 59
INT V152; // @ ST34_4 60
INT v153; // @ ST34_4 61
INT v154; // @ ST24_4 61
INT V155; // @ EAX 61
INT v156; // @ ST34_4 62
INT V157; // @ ST24_4 62
浮V158; // @ ST20_4 62
INT v159; // @ ST1C_4 62
INT V160; // @ ST18_4 62
INT V161; // @ ST14_4 62
INT V162; // @ EAX 62
INT V163; // @ ST34_4 63
INT V164; // @ EAX 63
INT v165; // @ ST34_4 64
INT V166; // @ EAX 64
INT V167; // @ ST34_4 65
INT V168; // @ EDI 65
INT V169; // @ ST34_4 66
INT V170; // @ EAX 66
INT V171; // @ ST34_4 68
INT V172; // @ EAX 68
INT V173; // @ EDX 69
INT v174; // @ ST34_4 69
漂浮v175; // @ ST34_4 69
INT V176; // @ ST34_4 72
INT V177; // @ ST34_4 73
INT v178; // @ ST34_4 74
unsigned int类型v179; // @ ST24_4 74
INT V180; // @ ST20_4 74
INT v181; // @ EAX 74
INT v182; // @ ST34_4 75
符号int v183; // @ ST24_4 75
INT v184; // @ ST20_4 75
INT V185; // @ EAX 75
INT V186; // @ ST34_4 76
为size_t v187; // @ ST24_4 76
INT V188; // @ ST20_4 76
INT v189; // @ EAX 76
INT V190; // @ ST34_4 77
浮V191; // @ ST34_4 77
INT v192; // @ ST34_4 78
浮V193; // @ ST34_4 78
双v194; // @ ST7 79
INT V195; // @ ST34_4 79
漂浮v196; // @ ST34_4 79
INT V197; // @ ST34_4 80
漂浮v198; // @ ST34_4 80
INT V199; // @ ST34_4 81
浮V200; // @ ST34_4 81
INT V201; // @ ST34_4 82
浮V202; // @ ST34_4 82
INT V203; // @ ST34_4 83
浮V204; // @ ST34_4 83
INT V205; // @ ST34_4 84
INT V206; // @ EDI 84
INT V207; // @ EAX 84
INT V208; // @ ST34_4 85
INT V209; // @ EDI 85
INT V210; // @ EAX 85
INT V211; // @ ST34_4 87
INT V212; // @ EDI 87
INT v213; // @ EAX 87
INT v214; // @ ST34_4 88
INT V215; // @ EDI 88
INT V216; // @ ST24_4 88
INT v217; // @ EAX 88
INT V218; // @ ST34_4 90
INT v219; // @ ST34_4 91
INT V220; // @ EAX 91
INT v221; // @ ST34_4 92
无符号整型V222; // @ ST24_4 92
INT v223; // @ ST20_4 92
INT v224; // @ ST1C_4 92
INT V225; // @ ST18_4 92
INT V226; // @ ST14_4 92
INT v227; // @ EAX 92
INT V228; // @ ST34_4 95
INT v229; // @ ST34_4 96
INT V230; // @ ST34_4 97
INT v231; // @ ST24_4 97
INT v232; // @ ST20_4 97
INT v233; // @ EAX 97
INT v234; // @ ST34_4 98
INT V235; // @ ST24_4 98
INT v236; // @ EAX 98
INT v237; // @ ST34_4 99
INT v238; // @ ST24_4 99
INT v239; // @ EAX 99
INT V240; // @ ST34_4 100
INT v241; // @ EAX 100
INT v242; // @ ST34_4 101
INT v243; // @ EAX 101
INT v244; // @ ST34_4 102
INT V245; // @ EAX 102
INT v246; // @ ST34_4 103
INT V247; // @ ST20_4 103
INT v248; // @ EAX 103
INT v249; // @ ST34_4 104
INT V250; // [SP-18H] [BP-30H] // @ 28
INT v251; // [SP-14H] [BP-CH〕28 @
INT v252; // [SP-10H] [BP-28H] // @ 28
INT v253; // [SP-CH] [BP-24小时] // @ 28
INT v254; // [SP-8H] [BP-20H] // @ 28
符号int V255; // [SP-4H] [BP-代上] // @ 28
INT v256; // [SP + 0H] [BP-18H] // @ 28
INT v257; // [SP + 4H] [BP-14H] // @ 28
INT v258; // [SP + 4H] [BP-14H] // @ 31 开关(*(_ DWORD *)V2)
{
情况下0:
V5 = VM_ArgPtr(*(_ DWORD *)(V4 + 4));
Com_Printf(%S,V5);
返回0; 情况1:
V7 = VM_ArgPtr(*(_ DWORD *)(V6 + 4));
Com_Error(1,%S,第7版);
返回结果; 案例2:
返回sub_447700(); 案例3:
V9 = *(_ DWORD *)(V8 + 16);
V10 = VM_ArgPtr(*(_ DWORD *)(V8 + 12));
V11 = VM_ArgPtr(*(_ DWORD *)(V8 + 8));
V12 = VM_ArgPtr(*(_ DWORD *)(V8 + 4));
sub_4213C0(V12,(为const char *)V11,V10,V9);
返回0; 情况4:
... 默认:
Com_Error(1,坏CGame的系统陷阱:%I,*(_ DWORD *)v249);
返回结果;
}
返回结果;
}
您可以在这里找到CL_CgameSystemCalls功能的完整(最后一个已知的官员)源(过多的复制粘贴):
http://ioqsrc.vampireducks.com/da/d3b/cl__cgame_8c- source.html
这是这里的老版本的反汇编,其中从修改系统调用调用orig_syscall工作:
的.text:00402B40; ===============子程序================================== =====
的.text:00402B40
的.text:00402B40
的.text:00402B40 sub_402B40 PROC附近; code XREF:sub_40B380 + BP
的.text:00402B40; sub_40E3B0 + BP ...
的.text:00402B40 MOV EDX,dword_BBE104
的.text:00402B46 MOV EAX,dword_CB60EC
的.text:00402B4B和EDX,0FFFFFFF7h
的.text:00402B4E TEST EAX,EAX
的.text:00402B50 MOV dword_BBE104,EDX
的.text:00402B56 MOV dword_BBE21C,0
的.text:00402B60 JZ短locret_402B82
的.text:00402B62推1
的.text:00402B64推EAX
的.text:00402B65通话sub_43E360
的.text:00402B6A MOV EAX,dword_CB60EC
的.text:00402B6F推EAX
的.text:00402B70通话sub_43E270
的.text:00402B75加ESP,0CH
的.text:00402B78 MOV dword_CB60EC,0
的.text:00402B82
的.text:00402B82 locret_402B82:; code XREF:sub_402B40 + 20J
的.text:00402B82 RETN
的.text:00402B82 sub_402B40 ENDP
的.text:00402B82
的.text:00402B82; -------------------------------------------------- -------------------------
的.text:00402B83对齐10H
的.text:00402B90
的.text:00402B90 loc_402B90:; DATA XREF:sub_403AA0 + 5CO
的.text:00402B90推ECX
的.text:00402B91推EBX
的.text:00402B92推ESI
的.text:00402B93推EDI
的.text:00402B94 MOV EDI,[ESP + 14H]
的.text:00402B98 MOV EAX,[EDI]
的.text:00402B9A CMP EAX,6FH;切换112箱子
的.text:00402B9D JA loc_4038C7;默认
的.text:00402B9D;跳转表00402BA3案件21,90-99,109,110
的.text:00402BA3 JMP DS:off_4038E0 [EAX * 4];开关跳
的.text:00402BAA
的.text:00402BAA loc_402BAA:; DATA XREF:的.text:off_4038E0o
的.text:00402BAA MOV EAX,[EDI + 4];跳转表00402BA3情况下0
的.text:00402BAD推EAX
的.text:00402BAE通话sub_43E300
的.text:00402BB3推EAX
的.text:00402BB4推抵消aS_7; %S
的.text:00402BB9通话sub_41BB90
的.text:00402BBE加ESP,0CH
的.text:00402BC1流行EDI
的.text:00402BC2流行ESI
的.text:00402BC3 XOR EAX,EAX
的.text:00402BC5流行EBX
的.text:00402BC6流行ECX
的.text:00402BC7 RETN
的.text:00402BC8; -------------------------------------------------- -------------------------
的.text:00402BC8
的.text:00402BC8 loc_402BC8:; code XREF:的.text:00402BA3j
的.text:00402BC8; DATA XREF:的.text:off_4038E0o
的.text:00402BC8 MOV ECX,[EDI + 4];跳转表00402BA3案例1
的.text:00402BCB推ECX
的.text:00402BCC通话sub_43E300
的.text:00402BD1推EAX
的.text:00402BD2推抵消aS_7; %S
的.text:00402BD7推1
的.text:00402BD9通话sub_41D850
的.text:00402BDE; -------------------------------------------------- -------------------------
有作为__usercall没有这样的事情。六角射线使用它来重新present非标准调用约定。这可以通过三种方式发生:
- 程序员使用的组件
- 的程序员使用公开赛在Watcom的
辅助的#pragma
自定义一个约定 - 的程序员使用的Visual C ++ 7+,这优化了寄存器分配到prevent颠簸
在这样的情况下,只有两条路走,用汇编或使用开放在Watcom(这只是得到了一个更新后遗弃多年的)。内联汇编作品最好的海事组织,但你需要一个包装将在(调用原件)和一个包装出来(勾原件)。
I have a virtual machine, which on VM_Create passes the address of a function (systemCalls) to the virtual machine.
So I hook VM_Create and steal the syscalls address, put it into a backup function pointer, and the address of my modified systemCalls function pass to the original VM_Create, from which I can alter arguments, add or remove calls, and then call the backed-up syscalls function. That worked well, until a new release of the game.
I believe to have found the problem:
This is the beginning of the unmodified systemCalls function:
intptr_t CL_CgameSystemCalls(intptr_t *args) {
switch (args[0]) {
case CG_PRINT:
Com_Printf( "%s", (const char*)VMA(1));
return 0;
case CG_ERROR:
Com_Error(ERR_DROP, "%s", (const char*)VMA(1));
return 0;
This is my modifed syscall function:
intptr_t modified_CL_CgameSystemCalls (intptr_t *args)
{
switch (*args)
{
case CG_GETSNAPSHOT:
mysnap = mysnap ;
mynextSnap = (snapshot_t*) (CG_QVM2NATIVE(args[2]));
mysnap = mynextSnap;
retval = original_CL_CgameSystemCalls(args);
break ;
The problem is calling the original function from the modified one:
intptr_t modified_CL_CgameSystemCalls(intptr_t *args)
{
retval = original_CL_CgameSystemCalls(args);
return retval;
}
already fails.
As you can see from the pseudocode of the disassembly, the new definition of CL_CgameSystemCalls seems to be:
char __usercall sub_4017B0<al>(int a1<ebx>, int a2)
Which means they changed the function by adding the __usercall attribute and by putting the first argument into register ebx, if I interpret the decompilation right.
Now my question:
How can I retrieve *args (args[0]) into a variable?
And how can I call the unmodified function from the modified one, which now uses __usercall?
This is the disassembly of systemcalls with usercall:
.text:004017B0 ; =============== S U B R O U T I N E =======================================
.text:004017B0
.text:004017B0
.text:004017B0 sub_4017B0 proc near ; DATA XREF: sub_402670+5Co
.text:004017B0
.text:004017B0 var_18 = dword ptr -18h
.text:004017B0 var_4 = dword ptr -4
.text:004017B0 arg_0 = dword ptr 4
.text:004017B0
.text:004017B0 ; FUNCTION CHUNK AT .text:00401430 SIZE 00000026 BYTES
.text:004017B0 ; FUNCTION CHUNK AT .text:00401459 SIZE 00000013 BYTES
.text:004017B0 ; FUNCTION CHUNK AT .text:00410E90 SIZE 00000006 BYTES
.text:004017B0 ; FUNCTION CHUNK AT .text:00412AC0 SIZE 00000006 BYTES
.text:004017B0
.text:004017B0 push esi
.text:004017B1 mov esi, [esp+0Ch+var_4]
.text:004017B5 mov eax, [esi]
.text:004017B7 cmp eax, 73h ; switch 116 cases
.text:004017BA push edi
.text:004017BB ja loc_402486 ; default
.text:004017BB ; jumptable 004017C1 cases 21,90-99,109,110
.text:004017C1 jmp ds:off_40249C[eax*4] ; switch jump
.text:004017C8
.text:004017C8 loc_4017C8: ; DATA XREF: .text:off_40249Co
.text:004017C8 mov eax, [esi+4] ; jumptable 004017C1 case 0
.text:004017CB push eax
.text:004017CC call VM_ArgPtr
.text:004017D1 push eax ; char
.text:004017D2 push offset aS_5 ; "%s"
.text:004017D7 call Com_Printf
.text:004017DC add esp, 0Ch
.text:004017DF pop edi
.text:004017E0 xor eax, eax
.text:004017E2 pop esi
.text:004017E3 retn
.text:004017E4 ; ---------------------------------------------------------------------------
.text:004017E4
.text:004017E4 loc_4017E4: ; CODE XREF: sub_4017B0+11j
.text:004017E4 ; DATA XREF: .text:off_40249Co
.text:004017E4 mov ecx, [esi+4] ; jumptable 004017C1 case 1
.text:004017E7 push ecx
.text:004017E8 call VM_ArgPtr
.text:004017ED push eax ; char
.text:004017EE push offset aS_5 ; "%s"
.text:004017F3 push 1 ; int
.text:004017F5 call Com_Error
.text:004017F5 ; --------------------------------------------------------------
And this is the pseudocode created from the hexrays decompiler:
char __usercall sub_4017B0<al>(int a1<ebx>, int a2)
{
int v2; // ST34_4@1
char result; // al@2
int v4; // ST34_4@2
int v5; // eax@2
int v6; // ST34_4@3
int v7; // eax@3
int v8; // ST34_4@5
int v9; // ST24_4@5
int v10; // ST20_4@5
int v11; // ST1C_4@5
int v12; // eax@5
int v13; // ST34_4@6
int v14; // eax@6
int v15; // ST34_4@7
int v16; // ST24_4@7
int v17; // eax@7
int v18; // ST34_4@8
signed int v19; // ST24_4@8
int v20; // ST20_4@8
int v21; // eax@8
int v22; // ST34_4@10
signed int v23; // ST24_4@10
int v24; // eax@10
int v25; // ST34_4@11
signed int v26; // ST24_4@11
int v27; // eax@11
int v28; // ST34_4@12
int v29; // ST24_4@12
int v30; // ST20_4@12
int v31; // eax@12
int v32; // ST34_4@13
int v33; // ST24_4@13
int v34; // ST20_4@13
int v35; // eax@13
int v36; // ST34_4@14
int v37; // ST24_4@14
size_t v38; // ST20_4@14
int v39; // eax@14
int v40; // ST34_4@15
int v41; // ST34_4@16
int v42; // ST34_4@17
int v43; // eax@17
int v44; // ST34_4@18
int v45; // eax@18
int v46; // ST34_4@19
int v47; // eax@19
int v48; // ST34_4@20
int v49; // eax@20
int v50; // ST34_4@22
int v51; // eax@22
void *v52; // ecx@22
int v53; // ST34_4@24
int v54; // ST20_4@24
int v55; // eax@24
int v56; // ST34_4@25
int v57; // ST20_4@25
int v58; // eax@25
int v59; // ST34_4@26
signed int v60; // ST24_4@26
int v61; // eax@26
int v62; // ST34_4@27
int v63; // ST24_4@27
int v64; // ST20_4@27
signed int v65; // ST1C_4@27
int v66; // eax@27
int v67; // ST34_4@28
int v68; // eax@29
int v69; // ST34_4@30
int v70; // ST34_4@32
int v71; // ST20_4@32
int v72; // ST1C_4@32
int v73; // ST18_4@32
signed int v74; // ST14_4@32
int v75; // ST10_4@32
int v76; // ST0C_4@32
int v77; // ST08_4@32
int v78; // ST04_4@32
int v79; // eax@32
int v80; // ST34_4@34
int v81; // ST24_4@34
int v82; // ST20_4@34
int v83; // ST1C_4@34
int v84; // ST18_4@34
int v85; // ST14_4@34
int v86; // eax@34
int v87; // ST34_4@35
int v88; // ST24_4@35
int v89; // ST20_4@35
int v90; // ST1C_4@35
int v91; // eax@35
int v92; // ST34_4@36
int v93; // ST34_4@37
int v94; // ST34_4@38
int v95; // ST24_4@38
int v96; // ST20_4@38
int v97; // eax@38
int v98; // ST34_4@39
int v99; // ST24_4@39
int v100; // ST20_4@39
int v101; // eax@39
int v102; // ST34_4@40
int v103; // ST34_4@41
int v104; // eax@41
int v105; // ST34_4@42
int v106; // ST20_4@42
int v107; // eax@42
int v108; // ST34_4@43
int v109; // eax@43
int v110; // ST34_4@44
int v111; // ST24_4@44
int v112; // eax@44
int v113; // ST34_4@45
int v114; // eax@45
int v115; // ST34_4@46
int v116; // eax@46
int v117; // ST34_4@47
int v118; // ST34_4@48
int v119; // ST34_4@49
int v120; // ST34_4@50
int v121; // ST24_4@50
int v122; // ST20_4@50
int v123; // eax@50
int v124; // ST34_4@52
int v125; // eax@52
int v126; // ST34_4@53
int v127; // eax@53
int v128; // ST34_4@54
int v129; // ST24_4@54
int v130; // eax@54
int v131; // ST34_4@55
int v132; // ST24_4@55
int v133; // ST20_4@55
int v134; // ST1C_4@55
int v135; // eax@55
int v136; // ST34_4@56
float v137; // ST24_4@56
float v138; // ST20_4@56
float v139; // ST1C_4@56
float v140; // ST18_4@56
int v141; // eax@56
int v142; // ST34_4@57
float v143; // ST24_4@57
float v144; // ST20_4@57
float v145; // ST1C_4@57
float v146; // ST18_4@57
int v147; // eax@57
int v148; // ST34_4@58
int v149; // eax@58
int v150; // ST34_4@59
int v151; // eax@59
int v152; // ST34_4@60
int v153; // ST34_4@61
int v154; // ST24_4@61
int v155; // eax@61
int v156; // ST34_4@62
int v157; // ST24_4@62
float v158; // ST20_4@62
int v159; // ST1C_4@62
int v160; // ST18_4@62
int v161; // ST14_4@62
int v162; // eax@62
int v163; // ST34_4@63
int v164; // eax@63
int v165; // ST34_4@64
int v166; // eax@64
int v167; // ST34_4@65
int v168; // edi@65
int v169; // ST34_4@66
int v170; // eax@66
int v171; // ST34_4@68
int v172; // eax@68
int v173; // edx@69
int v174; // ST34_4@69
float v175; // ST34_4@69
int v176; // ST34_4@72
int v177; // ST34_4@73
int v178; // ST34_4@74
unsigned int v179;// ST24_4@74
int v180; // ST20_4@74
int v181; // eax@74
int v182; // ST34_4@75
signed int v183; // ST24_4@75
int v184; // ST20_4@75
int v185; // eax@75
int v186; // ST34_4@76
size_t v187; // ST24_4@76
int v188; // ST20_4@76
int v189; // eax@76
int v190; // ST34_4@77
float v191; // ST34_4@77
int v192; // ST34_4@78
float v193; // ST34_4@78
double v194; // st7@79
int v195; // ST34_4@79
float v196; // ST34_4@79
int v197; // ST34_4@80
float v198; // ST34_4@80
int v199; // ST34_4@81
float v200; // ST34_4@81
int v201; // ST34_4@82
float v202; // ST34_4@82
int v203; // ST34_4@83
float v204; // ST34_4@83
int v205; // ST34_4@84
int v206; // edi@84
int v207; // eax@84
int v208; // ST34_4@85
int v209; // edi@85
int v210; // eax@85
int v211; // ST34_4@87
int v212; // edi@87
int v213; // eax@87
int v214; // ST34_4@88
int v215; // edi@88
int v216; // ST24_4@88
int v217; // eax@88
int v218; // ST34_4@90
int v219; // ST34_4@91
int v220; // eax@91
int v221; // ST34_4@92
unsigned int v222;// ST24_4@92
int v223; // ST20_4@92
int v224; // ST1C_4@92
int v225; // ST18_4@92
int v226; // ST14_4@92
int v227; // eax@92
int v228; // ST34_4@95
int v229; // ST34_4@96
int v230; // ST34_4@97
int v231; // ST24_4@97
int v232; // ST20_4@97
int v233; // eax@97
int v234; // ST34_4@98
int v235; // ST24_4@98
int v236; // eax@98
int v237; // ST34_4@99
int v238; // ST24_4@99
int v239; // eax@99
int v240; // ST34_4@100
int v241; // eax@100
int v242; // ST34_4@101
int v243; // eax@101
int v244; // ST34_4@102
int v245; // eax@102
int v246; // ST34_4@103
int v247; // ST20_4@103
int v248; // eax@103
int v249; // ST34_4@104
int v250; // [sp-18h] [bp-30h]@28
int v251; // [sp-14h] [bp-2Ch]@28
int v252; // [sp-10h] [bp-28h]@28
int v253; // [sp-Ch] [bp-24h]@28
int v254; // [sp-8h] [bp-20h]@28
signed int v255; // [sp-4h] [bp-1Ch]@28
int v256; // [sp+0h] [bp-18h]@28
int v257; // [sp+4h] [bp-14h]@28
int v258; // [sp+4h] [bp-14h]@31
switch (*(_DWORD *)v2)
{
case 0:
v5 = VM_ArgPtr(*(_DWORD *)(v4 + 4));
Com_Printf("%s", v5);
return 0;
case 1:
v7 = VM_ArgPtr(*(_DWORD *)(v6 + 4));
Com_Error(1, "%s", v7);
return result;
case 2:
return sub_447700();
case 3:
v9 = *(_DWORD *)(v8 + 16);
v10 = VM_ArgPtr(*(_DWORD *)(v8 + 12));
v11 = VM_ArgPtr(*(_DWORD *)(v8 + 8));
v12 = VM_ArgPtr(*(_DWORD *)(v8 + 4));
sub_4213C0(v12, (const char *)v11, v10, v9);
return 0;
case 4:
...
default:
Com_Error(1, "Bad cgame system trap: %i", *(_DWORD *)v249);
return result;
}
return result;
}
You can find the full (last known official) source of the CL_CgameSystemCalls function here (too much to copy-paste):
http://ioqsrc.vampireducks.com/da/d3b/cl__cgame_8c-source.html
And this here is the disassembly of the old version, in which calling orig_syscall from modified syscall worked:
.text:00402B40 ; =============== S U B R O U T I N E =======================================
.text:00402B40
.text:00402B40
.text:00402B40 sub_402B40 proc near ; CODE XREF: sub_40B380+Bp
.text:00402B40 ; sub_40E3B0+Bp ...
.text:00402B40 mov edx, dword_BBE104
.text:00402B46 mov eax, dword_CB60EC
.text:00402B4B and edx, 0FFFFFFF7h
.text:00402B4E test eax, eax
.text:00402B50 mov dword_BBE104, edx
.text:00402B56 mov dword_BBE21C, 0
.text:00402B60 jz short locret_402B82
.text:00402B62 push 1
.text:00402B64 push eax
.text:00402B65 call sub_43E360
.text:00402B6A mov eax, dword_CB60EC
.text:00402B6F push eax
.text:00402B70 call sub_43E270
.text:00402B75 add esp, 0Ch
.text:00402B78 mov dword_CB60EC, 0
.text:00402B82
.text:00402B82 locret_402B82: ; CODE XREF: sub_402B40+20j
.text:00402B82 retn
.text:00402B82 sub_402B40 endp
.text:00402B82
.text:00402B82 ; ---------------------------------------------------------------------------
.text:00402B83 align 10h
.text:00402B90
.text:00402B90 loc_402B90: ; DATA XREF: sub_403AA0+5Co
.text:00402B90 push ecx
.text:00402B91 push ebx
.text:00402B92 push esi
.text:00402B93 push edi
.text:00402B94 mov edi, [esp+14h]
.text:00402B98 mov eax, [edi]
.text:00402B9A cmp eax, 6Fh ; switch 112 cases
.text:00402B9D ja loc_4038C7 ; default
.text:00402B9D ; jumptable 00402BA3 cases 21,90-99,109,110
.text:00402BA3 jmp ds:off_4038E0[eax*4] ; switch jump
.text:00402BAA
.text:00402BAA loc_402BAA: ; DATA XREF: .text:off_4038E0o
.text:00402BAA mov eax, [edi+4] ; jumptable 00402BA3 case 0
.text:00402BAD push eax
.text:00402BAE call sub_43E300
.text:00402BB3 push eax
.text:00402BB4 push offset aS_7 ; "%s"
.text:00402BB9 call sub_41BB90
.text:00402BBE add esp, 0Ch
.text:00402BC1 pop edi
.text:00402BC2 pop esi
.text:00402BC3 xor eax, eax
.text:00402BC5 pop ebx
.text:00402BC6 pop ecx
.text:00402BC7 retn
.text:00402BC8 ; ---------------------------------------------------------------------------
.text:00402BC8
.text:00402BC8 loc_402BC8: ; CODE XREF: .text:00402BA3j
.text:00402BC8 ; DATA XREF: .text:off_4038E0o
.text:00402BC8 mov ecx, [edi+4] ; jumptable 00402BA3 case 1
.text:00402BCB push ecx
.text:00402BCC call sub_43E300
.text:00402BD1 push eax
.text:00402BD2 push offset aS_7 ; "%s"
.text:00402BD7 push 1
.text:00402BD9 call sub_41D850
.text:00402BDE ; ---------------------------------------------------------------------------
There is no such thing as __usercall. Hex-rays uses this to represent a non-standard calling convention. This can happen in three ways:
- The programmer used assembly
- The programmer is using Open Watcom's
#pragma aux
to define a custom convention - The programmer is using Visual C++ 7+, which optimizes register allocation to prevent thrashing
In cases like this, there are only two ways to go, use assembly or use Open Watcom (which just got an update after years of abandonment). Inline assembly works best IMO, but you'll need a wrapper going in (to call the original) and a wrapper coming out (to hook the original).
这篇关于挂钩usercall功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!