首页
社区
课程
招聘
1
十多年前未公开的反调试 - WindowByte反调试
发表于: 2024-6-27 23:44 4210

十多年前未公开的反调试 - WindowByte反调试

2024-6-27 23:44
4210
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
typedef LONG (WINAPI* WINDOWSBYTE)(intint);
bool CheckDebug()
{
    DWORD dwRet = 0;
    char szModuleName[15] = {0x75, 0x73, 0x65, 0x72, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C}; // user32.dll
    PWCHAR lpModuleName = NULL;
    PWCHAR lpModuleNameTemp = NULL;
    PCHAR lpSrc = szModuleName;
    DWORD dwAPI = 0;
    DWORD dwFunName = 0;
    DWORD dwBase = 0;
     
    _asm
    {
        xor ecx, ecx
        mov esi, fs: [0x30]
        mov esi, [esi + 0x0c]
        mov esi, [esi + 0x1c]
next_module:
         
        mov eax, [esi+0x8]
        cmp eax, 0
        je end
        mov edi,[esi+0x20]
        mov esi ,[esi]
 
        mov dwBase, eax
        mov lpModuleName, edi
        mov lpModuleNameTemp, edi
    }
     
    lpSrc = szModuleName;
    while(*lpModuleNameTemp != 0 && *lpSrc != 0)
    {
        if(*lpModuleNameTemp >= 'A' && *lpModuleNameTemp <= 'Z')
        {
            if(*lpModuleNameTemp != *lpSrc-0x20)
            {
                _asm
                {
                    jmp next_module
                }
            }
            else
            {
                lpSrc++;
                lpModuleNameTemp++;
            }
        }
        else if(*lpModuleNameTemp != *lpSrc)
        {
            _asm
            {
                jmp next_module
            }
        }
        else
        {
            lpSrc++;
            lpModuleNameTemp++;
        }
    }
 
end:
 
     
    PIMAGE_DOS_HEADER pDosHeader;
    PIMAGE_NT_HEADERS pNtHeader;
    PIMAGE_EXPORT_DIRECTORY pExportDirectory;
     
    char szFunName[15] = {0x47, 0x65, 0x74, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x4C, 0x6F, 0x6E, 0x67, 0x41, 0x00}; // GetWindowLongA
     
     
    pDosHeader = (PIMAGE_DOS_HEADER)dwBase;
    pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)dwBase + pDosHeader->e_lfanew);
    pExportDirectory = PIMAGE_EXPORT_DIRECTORY(pNtHeader->OptionalHeader.DataDirectory[0].VirtualAddress + (PBYTE)dwBase);
     
    PDWORD pAddressName = PDWORD((PBYTE)dwBase+pExportDirectory->AddressOfNames);
    PWORD pAddressOfNameOrdinals = (PWORD)((PBYTE)dwBase+pExportDirectory->AddressOfNameOrdinals);
    PDWORD pAddresOfFunction = (PDWORD)((PBYTE)dwBase+pExportDirectory->AddressOfFunctions);
     
    for(DWORD i = 0; i < pExportDirectory->NumberOfNames; i++)
    {
        PCHAR pFunc = (PCHAR)((PBYTE)dwBase + *pAddressName++);
         
        // printf("%s\r\n", pFunc);
         
        if (0 == strcmp(pFunc, szFunName))
        {
            dwAPI = (DWORD)dwBase + pAddresOfFunction[*pAddressOfNameOrdinals];
            break;
        }
         
        pAddressOfNameOrdinals++;
    }
 
    WINDOWSBYTE WindowsByte = (WINDOWSBYTE)dwAPI;
 
    for(int j = 0; j < 0xffffff; j++)
    {
        dwRet = WindowsByte(j, 0);
         
        // 1.x OD
        if(0x4cd6a8 == dwRet ||
            0x4cda75 == dwRet ||
            0x4cde42 == dwRet)
        {
            return TRUE;
        }
         
        // 2.x OD
        if(0x5e63c4 == dwRet ||
            0x5e6ab8 == dwRet ||
            0x5e6d24 == dwRet ||
            0x5e6fa8 == dwRet ||
            0x5e76b4 == dwRet)
        {
            return TRUE;
        }
    }
 
    return false;
}
 
 
char szCheckDebug[] =
"u\"Unpublicized anti-debug by cpudbg 冭貾YIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BB"
"ABXP8ABuJI3eLKZLOsZL1hscRvaGkwBezlGpS05Pwpo6g5jL3Ekv3uHmpszfg5ZNREKv75zORRZfqU8pUc"
"IVReya7BIVqUkBVNjfaUhs2Do6reKD2L9VG5huPlvSKpniReXvMXW5kJo7SuYtUPePwpS0YWRekXs0s0uP"
"EPLMPM8lMYrmMxKwreoPS0GpuPwpjgaUoLWpWpuPePo7SuyPgpUPWpuPUcKyrDlKtuDpc0GpUPLK1fVlNk"
"0v5LnkQVwxNcXxs06olDOUwpWpwpLK1nUpNkvVlICu9PoyQmItoySMYxLMRuzLNi65lhNkPExh6SKy0flK"
"Vhouky4OotOqUPuPC0lKPU98VoMnC2nekpD4QglKpMM8ecKbE6LKtQMSzZg1alvZLKsuKXucjiavnk4HNc"
"l9PZ3O4mlK3eyxuckpBFlKfblKPMoXdOMnDQMSJJ7P7KYRadwtHkOeJKUBlKW5LhMSkpwqk9qUMxNkPMKX"
"ncKqgrnibmKXZKfKLKqEKXecKpQvlKS2lKRmoX6oONtQekO244uWM9Qxyo9o9oZKvrLKreY8mSIPGqK9Cu"
"OXNkpMJHosKquRmY0MYxYy2OIokOyokvpEN4CwIVQUzupeJfpEZvsDKv75XW67KvsuzxQyjfW5Jy0nkvQU"
"KjsTKvaUKkbOhFSuYLBW8FpEyMpLHFSuyN2OhFCuKo2No6BekP0g8FQUyqQQHFre8b7pnkru9PoyBuN0LK"
"QUN0nkRmkp4CqXUlmYPMx4lKceMdlK2ekpS3g2d8k9w5OTNkpMMtlKPUKp6cpQQ0k9buNLNkSuy4lKrmiP"
"C3bhVDk9rmlpNkSei4NkqUKpfcqRELk9QUZdKwPEXHUPS05PUPjKuYnk0MKxmSzaUQMYPMZhlK65mtlKSu"
"JhgKpBVxvoNcZ5UPuP30nkRmLllKaEO0VcTQMYPUOlnkg5nLOsKpvdmYG5NLlM2mZtLIpMnxlKQEolK9qE"
"ntNkrez4Nj38mX2mNsNk0UlXujTJ2UFNop3MNs7pQdUOlKBeodMZW8UQMXPMLRnk3enxDzQZUQPu4Wk3w5"
"odeRLCqUlXwrOpsMZ2Gp2UxLJgw5lLePgpwps0xks8EKiPNcJx9oMYW5lLLK0MnlMY2mMXMSQmNhwp3Ewf"
"LKRuNPgCKpqvNkS2nkpMhDnkV5KpvcTTK1Oyv590zKVnNkQUnPK3kp4BMYaU80KY0SkOIo9oLKPMOPOypM"
"KL8GqULxS0uPePWpxkTInkV5LxOszbGqoyruX8MQcMMhkOkODOePSMSnrJUPnkG5MhPPkOrukLLIRezlOq"
"cMXLnHkfBlePbTdRna1mzl0uzzRlePPtUYmQQmZlcrYNblgpQeGtLpeQZKp5k13MxLITQsSns0qdEtk1SM"
"xLoHsZqNWp44eKNaQmzlvDrMsngpt4gbmQQmXLlhpo3nwpD4WyoqSMZlMdrVsngppugtnPuQzKWtZKNpgB"
"KpsoSnqKLKm53mQKjcz0LPLPlPEPHappy birthday, my brave girl :)lmYPMx4lKceMdlK2ekpS3g";
 
int main(int argc, char* argv[])
{
    bool bFound = false;
 
    // shellcode version
    _asm
    {
        lea eax, szCheckDebug
        call eax
        mov bFound, al
    }
    if(bFound)
    {
        MessageBox(NULL, "shellcode version, Found ollydbg!"":(", MB_ICONERROR);
    }
    else
    {
        MessageBox(NULL, "shellcode version, Not found ollydbg!"":)", MB_ICONINFORMATION);
    }
 
 
    // c version
    if(CheckDebug())
    {
        MessageBox(NULL, "c version, Found ollydbg!"":(", MB_ICONERROR);
    }
    else
    {
        MessageBox(NULL, "c version, Not found ollydbg!"":)", MB_ICONINFORMATION);
    }
 
    return 0;
}


还记得刚接触od那段时间,把od里三层外三层都研究了个遍,恨不得od的每一个字节都不放过.这个反调试也就是那时候发现的.
由于我对反调试不怎么感冒.这个反调试就慢慢的被遗忘了,直到前段时间,项目需求是必须要加上反调试.起初在网上找了许多反调试代码.
这些anti从环3到环0 从进程到内存 从窗口到特征 从嘀嗒差到debugapi 等等 各式各样的, 甚至还有检测进程目录下是否有 dbghelp plugin 等字样的.
这些anti有的很经典 有的检测环境苛刻 有的误判率过高  这些anti网上几乎都有相应的anti anti插件或方法绕过检测.
感觉都不尽如人意,这才让我想起了这个沉睡了10多年的反调试. WindowByte反调试.


<十多年前未公开的反调试 - WindowByte反调试>
优点: 误报率为0(代码写完善的情况下)
缺点: 只争对OD检测


不知od作者当初是有意栽花? 还是无意插柳?


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2024-6-28 23:19 被CpuDbg编辑 ,原因: 添加C语言版本
收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
cxbcxb
非常支持你的观点!
2024-6-30 21:39
最新回复 (8)
雪    币: 10529
活跃值: (1775)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
2
现在大多都用x64dbg了,od少了
2024-6-28 07:45
0
雪    币: 186
活跃值: (960)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
你这种方式 和搜索进程有啥区别啊 ,只要od打开了 就算嘛
2024-6-28 09:38
0
雪    币: 4
活跃值: (3750)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
直接给给ASM源码吧, 另外检测的底层逻辑是什么,能不能先说一下?
2024-6-28 19:07
0
雪    币: 537
活跃值: (279)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
wx_冰川 你这种方式 和搜索进程有啥区别啊 ,只要od打开了 就算嘛
那还是不一样的, 搜索进程,有很多插件都会隐藏进程的.
2024-6-28 23:20
0
雪    币: 537
活跃值: (279)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
咖啡_741298 直接给给ASM源码吧, 另外检测的底层逻辑是什么,能不能先说一下?
我已经更新C语言代码 :)
2024-6-28 23:21
0
雪    币: 4
活跃值: (3750)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
CpuDbg 我已经更新C语言代码 :)
关键是调用GetWindowLongA是把?  我记得vxk给了一个更隐蔽的方法一击必杀OD的, 类似于windowEventHook
2024-6-29 00:37
0
雪    币: 117
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
现在都是VT
2024-6-29 14:39
0
雪    币: 4837
活跃值: (4778)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9

优秀,发现的人用心了,感谢分享   


作者用SetWindowLong  DWL_MSGRESULT   保存了窗口的全局变量.       和 SetProp 之类的保存信息差不多. 

最后于 2024-6-29 20:24 被Mxixihaha编辑 ,原因:
2024-6-29 19:51
1
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册