首页
社区
课程
招聘
[原创][封装]动态汇编引擎与反汇编引擎
发表于: 17小时前 970

[原创][封装]动态汇编引擎与反汇编引擎

17小时前
970
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
#ifndef __GENIE_ASM_H
#define __GENIE_ASM_H
// 精灵动态汇编库
#ifdef __cplusplus
#define WIN32_LEAN_AND_MEAN             // 从 Windows 头中排除极少使用的资料
// Windows 头文件:
#include <windows.h>
 
#ifdef GENIEASM_EXPORTS
#include "Genieasm_Aux.h"
#define GENIEASM_API extern "C" __declspec(dllexport)
#else
#define GENIEASM_API extern "C" __declspec(dllimport)
// 数据类型:指令
typedef char instruction[80];
#endif
#else
 
#ifndef UInt64
#if defined(_WIN64)
typedef unsigned long long  UIntPtr;
#else
typedef unsigned int        UIntPtr;
#endif
typedef unsigned long long  UInt64;
#endif
 
#define GENIEASM_API extern
// 数据类型:指令
typedef char instruction[80];
#endif
 
//---------------------------------------------------------------------------------------------------
// @ 程序环境
//---------------------------------------------------------------------------------------------------
typedef void * Genie_Program_Environment;
// 创建环境
Genie_Program_Environment * geniepenv_create(BOOL platform64, UIntPtr address, UInt64 virtualAddr/* 基地址 */);
// 销毁环境
void geniepenv_destroy(Genie_Program_Environment * pGpenv);
//---------------------------------------------------------------------------------------------------
// @ 反汇编引擎
//---------------------------------------------------------------------------------------------------
// 进入反汇编环境
GENIEASM_API BOOL           geniedisasm_enter_env(Genie_Program_Environment * pGpenv);
// 反汇编开始 返回字符串地址
GENIEASM_API char *         geniedisasm_begin(UInt64 address);
// 反汇编
GENIEASM_API int            geniedisasm();
// 取当前地址
GENIEASM_API UINT64         geniedisasm_geteip();
// 反汇编结束
GENIEASM_API void           geniedisasm_end();
// 取函数真实地址
GENIEASM_API UINT64         geniedisasm_getrealfunadr(UInt64 address);
// 取指定长度的指令集
GENIEASM_API unsigned int   geniedisasm_query(UInt64 address, unsigned int size, instruction * instrs, unsigned int nbInstr);
// 退出反汇编环境
GENIEASM_API void           geniedisasm_leave_env();
 
//---------------------------------------------------------------------------------------------------
// @ 反汇编引擎宏
//---------------------------------------------------------------------------------------------------
static char * m_pszInstr = NULL;
#define __disasm_enter(ENV)                  if (geniedisasm_enter_env(ENV) == TRUE) { do
#define __disasm_begin(ADR)                  m_pszInstr = geniedisasm_begin((UInt64)ADR); if (m_pszInstr != NULL) { char * instr = m_pszInstr; do
#define __disasm                             geniedisasm()
#define __disasmFrealadr(FUN)                geniedisasm_getrealfunadr((UInt64)FUN)
#define __disasm_end                         while(0); geniedisasm_end(); }
#define __disasmX(ADR,_SIZE, INSTR, NBINSTR) geniedisasm_query((UInt64)ADR, (unsigned int)_SIZE, INSTR, NBINSTR)
#define __disasm_leave                       while(0); geniedisasm_leave_env(); }
//---------------------------------------------------------------------------------------------------
// @ 汇编引擎
//---------------------------------------------------------------------------------------------------
// 汇编
#ifdef _DEBUG
// 设置编译名称
GENIEASM_API void     genieassembly_setname(char * name);
// 设置错误回调
typedef void(_cdecl * on_assembly_error)(const char * name, const char * pszCode, const char * msg);
GENIEASM_API void     genieassembly_seterr(on_assembly_error error);
#else
#define genieasm_assembly_seterr
#define genieasm_assembly_setname
#endif
// 进入汇编环境(默认环境 当前程序环境)
GENIEASM_API BOOL    genieassembly_enter_env(Genie_Program_Environment * pGpenv);
// 投递空间域
GENIEASM_API BOOL    genieassembly_push_space(UInt64 address, unsigned int size);
// 汇编开始 (dest == NULL){使用已经存在的汇编地址(genieasm_assembly_push_space 提供的空间域)}
GENIEASM_API BOOL    genieassembly_begin(UInt64 address, unsigned int size);
// 汇编开始 从dest目标处查找首个nop指令作为编译地址
/*
// 汇编静态与动态结合
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
        }
    }
}
    // 这种代码难理解
    genieassembly_begin_search_nop(genieassembly_getrealfunadr((UIntPtr)FUNCTION));
        genieassembly_fmt("push 0x%x", gameActskill);
        genieassembly_to_nop();
        genieassembly_fmt("call 0x%x", gameActcall);
    genieasm_assembly_end();
 
    // 使用宏封装代码
 
    __masmSearchNop(FUNCTION) {
        __masmF("push 0x%x", gameActskill);
        __masmMtnop;
        __masmF("call 0x%x", gameActcall);
    }__masm__;
*/
// 开始汇编于NOP
GENIEASM_API BOOL    genieassembly_begin_search_nop(UInt64 address, BOOL searchE);
// 开始汇编于特征码 遇到 0x90 跳过识别
GENIEASM_API BOOL    genieassembly_begin_search_features(UInt64 address, unsigned int size, UIntPtr features, unsigned int sizeFeatures);
// 跳过指定字节
GENIEASM_API void    genieassembly_skip(unsigned int size);
// 跳至NOP
GENIEASM_API void    genieassembly_to_nop();
// 汇编文本
GENIEASM_API void    genieassembly_str(char * pszCode);
// 连续汇编      genieasm_assembly_coiled("push 0", "push 1", NULL);
GENIEASM_API void    genieassembly_coiled(char * pszCode,...);
// 格式化文本汇编 genieasm_assembly_fmt("push 0x%x", 1024);
GENIEASM_API void    genieassembly_fmt(char * pszCode, ...);
// 汇编指令集(反汇编过来的指令集)
GENIEASM_API void    genieassembly_instrs(instruction * instrs, unsigned int nbInster);
// 插入机器码
GENIEASM_API void    genieassembly_placemc(UInt64 address, unsigned int size);
// 插入机器码(源地址与环境无关)
GENIEASM_API void    genieassembly_placemcne(LPVOID address, unsigned int size);
 
// 转录指令(源地址(与环境相关),指令长度, -1:不可以超出 0:绝对指令长度 1:可以超出)
GENIEASM_API unsigned int genieassembly_translated(UInt64 address, unsigned int size, int flag);
 
// 取当前eip
GENIEASM_API UInt64  genieassembly_geteip();
// 填充NOP
GENIEASM_API void    genieassembly_fillNop(unsigned int size); // 设置为 NOP
// 取函数真实地址
GENIEASM_API UINT64  genieassembly_getrealfunadr(UInt64 address);
 
// 结束汇编(size 返回编译的机器字节数)
GENIEASM_API void    genieassembly_end(unsigned int * size);
// 退出汇编环境
GENIEASM_API void    genieassembly_leave_env();
 
// 直接汇编(与环境无关)
GENIEASM_API unsigned int genieassembly(UIntPtr adr, UIntPtr adrV, char * pszInstrF, ...);
// 非汇编 插入机器码(目标地址(与环境相关), 源地址(与环境相关), 指令长度)
GENIEASM_API void    genieassembly_placemcany(UInt64 dest, UInt64 machine, unsigned int size);
// 非汇编 插入机器码(目标地址(与环境相关), 源地址(与环境无关), 指令长度)
GENIEASM_API void    genieassembly_placemcanyne(UInt64 dest, LPVOID machine, unsigned int size);
// 非汇编 读取内存
GENIEASM_API void    genieassembly_readany(LPVOID dest, UInt64 address, unsigned int size);
//---------------------------------------------------------------------------------------------------
// @ 汇编引擎宏
//---------------------------------------------------------------------------------------------------
#define __masm_enter(ENV)             if (genieassembly_enter_env(ENV) == TRUE) { do
#define __masm_define_space(ADR, _SIZE) genieassembly_push_space((UInt64)ADR, (unsigned int)_SIZE)
#define __masmFrealadr(FUN)           genieassembly_getrealfunadr((UInt64)FUN)
#define __masm(ADR, _SIZE)            if (genieassembly_begin((UInt64)ADR, (unsigned int)_SIZE) == TRUE) { do
#define __masmX(_SIZE)                __masm(0, _SIZE)
// 查找首尾NOP进行汇编
#define __masmSearchNop(ADR)          if (genieassembly_begin_search_nop(__masmFrealadr(ADR), FALSE) == TRUE) { do
// 查找首NOP进行汇编
#define __masmSearchNopE(ADR)         if (genieassembly_begin_search_nop(__masmFrealadr(ADR), TRUE) == TRUE) { do
#define NOP -1
#define __masmMtnop                   genieassembly_to_nop();
#define __masmSkip(L)                 genieassembly_skip
#define __masmC(CODE)                 genieassembly_str(CODE)
#define __masmS(...)                  genieassembly_coiled(__VA_ARGS__, NULL)
#define __masmI                       genieassembly_instrs
#define __masmF(...)                  genieassembly_fmt(__VA_ARGS__)
// ADR(与环境相关)
#define __masmM(ADR, _SIZE)           genieassembly_placemc((UIntPtr)ADR, (unsigned int)_SIZE)
// ADR(与环境无关)
#define __masmMne(ADR, _SIZE)         genieassembly_placemcne((LPVOID)ADR, (unsigned int)_SIZE)
// 读取
#define __masmNOP(_SIZE)              genieassembly_fillNop(_SIZE)
#define __masmEIP                     genieassembly_geteip()
// 转录代码
#define __masmTran                    genieassembly_translated
#define __masm__                      while(0); genieassembly_end(NULL); }
#define __masmL__(_SIZE)              while(0); genieassembly_end(&_SIZE); }
#define __masm_leave                  while(0); genieassembly_leave_env(); }
 
// 非汇编指令集(目标地址(与环境相关), 源地址(与环境无关), 指令长度)
#define __code_place(ADR, MCADR, _SIZE)   genieassembly_placemcany((UInt64)ADR, (UInt64)MCADR, (unsigned int)_SIZE)
#define __code_placeNE(ADR, MCADR, _SIZE) genieassembly_placemcanyne((UInt64)ADR, (LPVOID)MCADR, (unsigned int)_SIZE)
// 读内存(目标地址(与环境无关), 原地址(与环境有关), 指令长度)
#define __code_read(DEST, ADR, _SIZE)     genieassembly_readany((LPVOID)DEST, (UInt64)ADR, (unsigned int)_SIZE)
 
// 调试
#ifdef _DEBUG
#define __masmError(FUN)            genieasm_assembly_seterr((genieasm_assembly_error)FUN)
#define __masmName(ASMNAME)         genieasm_assembly_setname(ASMNAME)
#else
#define __masmName(ASMNAME)
#endif
// 单行汇编
#define __assemblyEx(ADR, VADR,...)  genieassembly((UIntPtr)ADR, (UIntPtr)VADR, __VA_ARGS__)
#define __assembly(ADR,...)          genieassembly((UIntPtr)ADR, 0, __VA_ARGS__)
 
//---------------------------------------------------------------------------------------------------
// @ 其他函数
//---------------------------------------------------------------------------------------------------
// 申请机器码内存
GENIEASM_API UIntPtr genieshellcode_alloc(unsigned int size);
// 释放机器码内存
GENIEASM_API void    genieshellcode_free(UIntPtr shellC);
 
//---------------------------------------------------------------------------------------------------
// @ 其他函数引擎宏
//---------------------------------------------------------------------------------------------------
#define __shellcode_alloc(_SIZE) genieshellcode_alloc
#define __shellcode_free(P)      genieshellcode_free(UIntPtr(P))
 
// 汇编与反汇编同时进入环境
GENIEASM_API BOOL geniepenv_enter(Genie_Program_Environment * env);
GENIEASM_API void geniepenv_leave();
//---------------------------------------------------------------------------------------------------
// @ 宏
//---------------------------------------------------------------------------------------------------
#define __env_enter(ENV) if (geniepenv_enter(ENV) == TRUE) { do
#define __env_leave      while(0); geniepenv_leave(); }
 
// PE 动态修改保存
#ifdef __PEMODIFY_DLL
 
/* 装载PE */
GENIEASM_API void * geniepe_load(char * pszFile);
/* 卸载PE */
GENIEASM_API void geniepe_unload(void * pe);
/* 另存为PE */
GENIEASM_API BOOL geniepe_saveas(char * pszFile, void * pe);
/* 取PE环境 */
GENIEASM_API Genie_Program_Environment * geniepe_getenv(void * pe);
//---------------------------------------------------------------------------------------------------
// @ PE汇编引擎宏
//---------------------------------------------------------------------------------------------------
#define __peload(_FILE)       geniepe_load(_FILE)
#define __peunload(PE)        geniepe_unload(PE)
#define __pesaveas(PE, _FILE) geniepe_saveas(_FILE, PE)
#define __peENV(PE)           geniepe_getenv(PE)
 
#else
 
#define __peload(PE)
#define __peunload(PE)
#define __pesaveas(_FILE, PE)
#define __peENV(PE)            NULL
 
#endif
 
typedef void * DETOUR;
 
// 衍生出来HOOK库
// 安装(源地址,跳转地址,指令对齐?, 启用线程安全?, 立即启用)
GENIEASM_API DETOUR geniedetour_install(UIntPtr src, UIntPtr dest, BOOL align, BOOL thrd, BOOL enable);
GENIEASM_API DETOUR geniedetour_installEx(UIntPtr src, UIntPtr dest, unsigned int dest_size, BOOL align, BOOL thrd, BOOL enable);
GENIEASM_API UIntPtr geniedetour_query_api(char * pszdllName, char * pszapiName);
// 卸载
GENIEASM_API void geniedetour_uninstall(DETOUR pDetour);
// 挂起
GENIEASM_API void geniedetour_suspend(DETOUR pDetour);
// 启动
GENIEASM_API void geniedetour_enable(DETOUR pDetour);
 
//---------------------------------------------------------------------------------------------------
// @ HOOK 引擎宏
//---------------------------------------------------------------------------------------------------
#define detour_install      geniedetour_install
#define detour_installEx    geniedetour_installEx
#define detour_query_api    geniedetour_query_api
#define detour_uninstall    geniedetour_uninstall
#define detour_suspend      geniedetour_suspend
#define detour_enable       geniedetour_enable
 
#endif

DEMO:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
#include "Genieasm.h"
#include <malloc.h>
__inline void enter()
{
#ifdef _WIN32
    Genie_Program_Environment * env = geniepenv_create(FALSE, 0, 0);
#else
    Genie_Program_Environment * env = geniepenv_create(TRUE, 0, 0);
#endif
    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);
    }
}
 
#ifdef _DEBUG
 
 
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();
}
 
 
 
 
 
#endif

ida查看修改后的pe


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
看不懂,能详细讲讲这是干啥的不,有哪些使用场景呢
14分钟前
0
游客
登录 | 注册 方可回帖
返回
//