程序入口特征:

1
2
3
4
5
6
7
8
9
VC6:GetVersion()

VS2005、VS2008、VS2017:GetSystemTimeAsFileTime()
call XXX
JMP YYY

DELPHI:GetMoulenHandle()

加壳:防止静态反编译
1
2
3
4
5
6
7
8
9
10
11
12
//寻找入口点:
语言:C
IDE:VS2022
编译器:MSVC

加壳工具:VMProtect Ultimate v3.8.4

保护选项:不开“虚拟/变异”,开启检测调试器,其余保持默认

入口点寻找方法:
1、在GetSystemTimeAsFileTime()下断点,F9两次;
2、在栈中观察,从上到下第三个返回值就是入口;


1
3、倒数第五个call就是 invoke_main();

1
4、进去invoke_main(),一个jmp之后就是main();
1
以上思路也可以应对TMD、Engima壳(保护是默认选项)

VM逆向,一篇就够了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//TLS回调函数检测调试器
#include <windows.h>

#pragma comment(linker, "/INCLUDE:__tls_used") //告知链接器将要使用TLS功能

void NTAPI TLS_CALLBACK(PVOID DllHandle, DWORD Reason, PVOID Reserved) //TLS回调函数
{
if (IsDebuggerPresent())
{
MessageBoxA(NULL, "Debugger Detected!", "TLS Callback", MB_OK);
ExitProcess(1);
}
}

#pragma data_seg(".CRT$XLX") //注册TLS回调函数
PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[] = { TLS_CALLBACK, 0 };
#pragma data_seg()

int main(void)
{
MessageBoxA(NULL, "Hello :)", "main()", MB_OK);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//花指令-异常处理滥用
MOV AX, 0
__try
{
DIV AX, 0 ; 故意触发除零异常
JMP normal_path
}
__except (1)
{
MOV BX, 1
JMP after_except
}
normal_path:
MOV BX, 2
after_except:
; 后续代码
//这里故意触发除零异常进入异常处理块,在异常处理块中插入一些与异常本身关联不大的代码
//(如简单设置 BX 寄存器值),并且通过跳转等方式使整个执行流程变得复杂,干扰逆向分析。
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
#include <stdio.h>
#include <windows.h>

int main() {
BOOL isDebugged = IsDebuggerPresent()-1;
__try
{
__asm
{
mov eax, 1
div isDebugged // 这里会触发除零异常(如果正在被调试)
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
// 异常处理块,加入干扰性代码
__asm
{
_emit 0xeb;
_emit 0xff;
_emit 0xcd;
_emit 0x03;
}
goto after_exception;
}
// 如果没有发生异常,正常会执行到这里输出相应信息
printf("程序正常执行");
return 0;
after_exception:
printf("从异常处理块跳转过来\n");
return 1;
}