__inline void enter()
{
Genie_Program_Environment
*
env
=
geniepenv_create(FALSE,
0
,
0
);
Genie_Program_Environment
*
env
=
geniepenv_create(TRUE,
0
,
0
);
geniepenv_enter(env);
genieassembly_enter_env(env);
}
__inline void leave()
{
geniedisasm_leave_env();
genieassembly_leave_env();
}
BOOL
geniepenv_enter(Genie_Program_Environment
*
env)
{
if
(env !
=
NULL)
{
if
(geniedisasm_enter_env(env)
=
=
TRUE)
{
if
(genieassembly_enter_env(env)
=
=
TRUE)
{
return
TRUE;
}
geniedisasm_leave_env();
}
}
return
FALSE;
}
void geniepenv_leave()
{
geniedisasm_leave_env();
genieassembly_leave_env();
}
BOOL
APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
enter();
break
;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break
;
case DLL_PROCESS_DETACH:
leave();
break
;
}
return
TRUE;
}
/
/
申请机器码内存
UIntPtr genieshellcode_alloc(unsigned
int
size)
{
if
(size !
=
0
)
{
unsigned char
*
shellC
=
(unsigned char
*
)malloc(size
+
sizeof(size_t)
+
sizeof(size_t));
if
(shellC !
=
NULL)
{
*
((unsigned
int
*
)shellC)
=
size;
shellC
+
=
sizeof(unsigned
int
);
shellC
+
=
sizeof(unsigned
int
);
::VirtualProtect(shellC, size, PAGE_EXECUTE_READWRITE, (PDWORD)&shellC[
0
-
sizeof(unsigned
int
)]);
return
(UIntPtr)shellC;
}
}
return
NULL;
}
/
/
释放机器码内存
void genieshellcode_free(UIntPtr shellC)
{
if
(shellC !
=
0
)
{
unsigned char
*
_FREE
=
(unsigned char
*
)shellC;
_FREE
-
=
sizeof(size_t);
DWORD dwProtect
=
*
((PDWORD)_FREE);
_FREE
-
=
sizeof(size_t);
size_t _SIZE
=
*
((unsigned
int
*
)_FREE);
DWORD dwCONST
=
0
;
::VirtualProtect((LPVOID)shellC, _SIZE, dwProtect, &dwCONST);
free(_FREE);
}
}
void __declspec(naked) FUNCTION2()
{
__asm
{
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
}
}
void __declspec(naked) FUNCTION3()
{
__asm
{
mov eax,
65537
;
mov eax,
65538
;
mov eax,
65536
;
mov eax,
65539
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
mov eax,
65536
;
}
}
/
/
汇编静态与动态结合
void __declspec(naked) FUNCTION(
int
arg)
{
__asm
{
push ebp;
mov ebp, esp;
push dword ptr[ebp
+
12
];
nop;
nop;
nop;
nop;
nop;
mov ecx, dword ptr[ebp
+
8
];
nop;
nop;
nop;
nop;
nop;
add esp,
4
;
pop ebp;
retn
8
}
}
void WINAPI hook_dest(char
*
pszMessage)
{
::MessageBox(NULL,
"流程正常"
, pszMessage, NULL);
}
BYTE m_shell[
0xff
];
BYTE m_shell2[
0x256
];
int
jmpCheck()
{
static
int
c
=
0
;
if
(c
=
=
0
)
{
printf(
"%d\r\n"
,
0
);
c
+
+
;
return
0
;
}
printf(
"%d\r\n"
,
1
);
return
1
;
}
void Func()
{
}
int
main()
{
enter();
/
/
使用当前程序环境 基地址
0
虚拟地址
0
32
位
/
/
汇编静态与动态结合
__masmSearchNop(FUNCTION)
{
__masmF(
"push 0x%x"
,
65536
);
__masmMtnop(NOP);
__masmF(
"call 0x%x"
, main);
}__masm__;
/
/
反汇编输出查看
__disasm_begin(__disasmFrealadr(FUNCTION))
{
int
line
=
9
;
while
(line
-
-
)
{
__disasm;
printf(
"%s\r\n"
, instr);
}
}__disasm_end;
getchar();
printf(
"--------------------------------------------\r\n"
);
/
/
嵌套汇编 与预制空间
__masm_define_space(m_shell,
0xFF
);
__masm_define_space(m_shell2,
0x256
);
__masmX(
48
)
{
__masmS(
"push ebp"
,
"mov ebp, esp"
,
"push 1"
,
"push 2"
);
UInt64 adrCall
=
0
;
__masmX(
46
)
{
adrCall
=
__masmEIP;
__masmS(
"push ebp"
,
"mov ebp, esp"
,
"mov eax, dword ptr [ebp+8]"
,
"mov esi, dword ptr [ebp+12]"
,
"add eax, esi"
,
"pop ebp"
,
"retn"
);
}__masm__;
__masmF(
"call 0x%x"
, (UIntPtr)adrCall);
__masmS(
"add esp, 8"
,
"pop ebp"
,
"retn"
);
}__masm__;
/
/
反汇编输出查看
__disasm_begin(m_shell)
{
int
line
=
8
;
while
(line
-
-
)
{
__disasm;
printf(
"%s\r\n"
, instr);
}
}__disasm_end;
__disasm_begin(m_shell2)
{
int
line
=
8
;
while
(line
-
-
)
{
__disasm;
printf(
"%s\r\n"
, instr);
}
}__disasm_end;
printf(
"--------------------------------------------\r\n"
);
printf(
"-HOOK START!!! {src:%x, dest:%x}-\r\n"
, (UIntPtr)__masmFrealadr(hook_dest), (UIntPtr)__masmFrealadr(FUNCTION2));
getchar();
instruction inster[
20
];
/
/
使用静态汇编进行HOOK
UInt64 hookD
=
__disasmFrealadr(hook_dest);
/
/
对齐
5
个指令长度
unsigned
int
len
=
__disasmX(hookD,
5
, inster,
20
);
UInt64 jmpD
=
__disasmFrealadr(FUNCTION2);
__masm(jmpD,
0xFF
)
{
__masmF(
"call 0x%x"
, jmpCheck);
__masmS(
"cmp eax, 0"
);
__masmF(
"jz 0x%x"
, __masmEIP
+
1
);
/
/
1
拦截
0
不拦截放行
__masmC(
"retn 4"
);
/
/
直接返回
__masmI(inster,
20
);
/
/
输入刚刚反编译的指令
__masmF(
"jmp 0x%x"
, hookD
+
len
);
/
/
跳到源函数
}__masm__;
/
/
指令对齐hook
__masm(hookD,
len
)
{
__masmF(
"jmp 0x%x"
, jmpD);
__masmNOP(
0
);
/
/
用 nop 对齐指令
}__masm__;
printf(
"--------------------------------------------\r\n"
);
printf(
"-HOOK OK! 使用OD下断吧,回车继续执行 CALL -\r\n"
);
getchar();
hook_dest(
"正常吗1"
);
hook_dest(
"正常吗2"
);
/
/
动态汇编测试结束
/
/
测试使用动态汇编永久修改exe
/
/
加载pe并进入pe环境
void
*
pe
=
__peload(
"E:GAME.client"
);
if
(pe !
=
NULL)
{
__env_enter(__peENV(pe))
/
/
汇编与反汇编进入pe环境
{
/
/
LOGO 窗口创建与窗口过程线程
__masm_define_space(
0x402320
,
116
);
__masm_define_space(
0x402550
,
400
);
__masm_define_space(
0x4023A0
,
296
);
__masm_define_space(
0x4038C0
,
106
);
__masm_define_space(
0x403530
,
908
);
__masm_define_space(
0x403430
,
241
);
__masm(
0x4092B9
,
0x4092E3
-
0x4092B9
) {
__masmC(
"xor esi, esi"
);
__masmC(
"jmp 0x4092E3"
);
__masmNOP(
0
);
}__masm__;
__disasm_begin(
0x4092B9
) {
int
line
=
42
;
while
(line
-
-
)
{
__disasm;
printf(
"%s\r\n"
, instr);
}
}__disasm_end;
/
/
线程里创建了 LOGO 动画
__masm(
0x4092EE
,
0x40931A
-
0x4092EE
)
{
__masmC(
"jnz 0x40931A"
);
__masmNOP(
0
);
}__masm__;
/
/
销毁LOGO
/
/
.text:
0040934D
jnz short loc_409359
__masm(
0x040934D
,
0x40937A
-
0x040934D
)
{
__masmC(
"jnz 0x40937A"
);
__masmNOP(
0
);
}__masm__;
/
/
判断是否是录像 直接跳过判断并注入DLL
/
/
永久注入个dll试试
__masm(
0x408FC1
,
0x40900A
-
0x408FC1
)
{
__masmC(
"push 0x409033"
);
/
/
409033
~
409207
__masmC(
"call dword ptr [0xF8E0E8]"
);
__masmC(
"jmp 0x409207"
);
/
/
修改后会有段空间地址空出来
468
个字节 直接用呗
__masmNOP(
0
);
}__masm__;
/
/
存在PE环境不能直接 memcpy
const char injectDLL[]
=
"test.dll"
;
__code_placeNE(
0x409033
, injectDLL, ::strlen(injectDLL)
+
sizeof(char));
char szDll[
65
];
__code_read(szDll,
0x409033
,
16
);
printf(
"set dll name : %s\r\n"
, szDll);
/
/
判断录像跳过
__masm(
0x409246
,
0x409261
-
0x409246
)
{
__masmC(
"jmp 0x409261"
);
__masmNOP(
0
);
}__masm__;
/
/
屏蔽掉多开提示
/
/
.text:
00403226
cmp
dword_117EA4C,
0
__masm(
0x0403226
,
0x403271
-
0x0403226
)
{
__masmC(
"jmp 0x403271"
);
__masmNOP(
0
);
}__masm__;
/
/
HOOK JMP CODE
UIntPtr jmpAdr
=
0
;
UIntPtr callNative
=
0
;
/
/
收包改写
unsigned
int
sizeHook
=
0
;
/
/
JMP ONRECV
__masmX(
50
)
{
jmpAdr
=
__masmEIP;
__masmS(
"push ebp"
,
"mov ebp, esp"
);
__masmS(
"push dword [ebp+0xC]"
,
"push dword [ebp+0x8]"
);
printf(
"OnRecv Set:0x%x \r\n"
, __masmEIP);
__masmF(
"call 0x%x"
, Func);
__masmC(
"pop ebp"
);
callNative
=
__masmEIP;
__masmC(
"mov ecx, ds:[0x1417440]"
);
/
/
__masmM(
0x6C5D20
,
8
);
/
/
首
8
字节没有涉及 JMP 直接 COPY 如果涉及 jmp 则需要转录
sizeHook
=
__masmTran(
0x6C5D20
,
5
,
1
);
/
/
转录 虽然只有
5
字节但反汇编处理
8
字节 都会转录过去 如果有跳转会自动计算跳转偏移
printf(
"转录代码长度:%d\r\n"
, sizeHook);
__masmF(
"jmp 0x%x"
,
0x6C5D28
);
}__masm__;
/
/
call 汇编码
__masmX(
50
)
{
printf(
"SendLoc Native Call:0x%x \r\n"
, __masmEIP);
__masmS(
"push ebp"
,
"mov ebp, esp"
,
"push dword [ebp+0x10]"
,
"push dword [ebp+0xC]"
,
"push dword [ebp+0x8]"
);
__masmF(
"call 0x%x"
, callNative);
__masmC(
"retn 0xC"
);
}__masm__;
/
/
HOOK
__masm(
0x6C5D20
, sizeHook)
/
/
这里直接HOOK转录时的代码长度 并使用nop对齐指令
{
__masmF(
"jmp 0x%x"
, jmpAdr);
__masmNOP(
3
);
}__masm__;
/
/
发包改写
/
/
JMP ONSEND
__masmX(
50
)
{
jmpAdr
=
__masmEIP;
__masmS(
"push ebp"
,
"mov ebp, esp"
,
"push dword [ebp+0x10]"
,
"push dword [ebp+0xC]"
);
printf(
"OnSend Set:0x%x \r\n"
, __masmEIP);
__masmF(
"call 0x%x"
, Func);
__masmC(
"pop ebp"
);
callNative
=
__masmEIP;
/
/
记录 本程序使用的 发包 call 入口 绕过HOOK
__masmC(
"mov ecx, ds:[1417434]"
);
__masmM(
0x6037A0
,
5
);
__masmC(
"jmp 0x6037A5"
);
}__masm__;
/
/
call 汇编码
__masmX(
50
)
{
printf(
"SendNet Native Call:0x%x \r\n"
, __masmEIP);
__masmS(
"push ebp"
,
"mov ebp, esp"
,
"push 0"
,
"push 1"
,
"push 1"
,
"push dword [ebp + 0xC]"
,
"push dword [ebp + 0x8]"
,
"push 0"
);
__masmF(
"call 0x%x"
, callNative);
__masmS(
"pop ebp"
,
"retn 0x8"
);
}__masm__;
__masm(
0x6037A0
,
5
)
/
/
HOOK
{
__masmF(
"jmp 0x%x"
, jmpAdr);
}__masm__;
/
/
自动寻路改写
/
/
初始化自动寻路 call 小于
10
时不触发
/
/
.text :
005CF64C
cmp
eax,
0Ah
/
/
.text :
005CF624
cmp
eax,
0Ah
__masm(
0x5CF64C
,
3
) { __masmC(
"cmp eax, 0"
); }__masm__;
__masm(
0x5CF624
,
3
) { __masmC(
"cmp eax, 0"
); }__masm__;
/
/
call 汇编码
__masmX(
50
)
{
printf(
"Moveto Native Call:0x%x \r\n"
, __masmEIP);
__masmS(
"push ebp"
,
"mov ebp, esp"
,
"push 0"
,
"push dword [ebp+0xC]"
,
"push dword [ebp+0x8]"
,
"call 0x7C22C0"
,
"pop ebp"
,
"retn 0x8"
);
}__masm__;
}__env_leave;
/
/
保存PE(用IDA查看吧)
/
/
__pesaveas(pe,
"E:GAME.client.new"
);
__peunload(pe);
}
getchar();
leave();
}