首页
社区
课程
招聘
7
[原创]未知壳乱序重构
发表于: 2008-1-15 19:44 7481

[原创]未知壳乱序重构

dummy 活跃值
23
2008-1-15 19:44
7481
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
很有趣<img src="/view/img/face/50.gif" width="24" height="24" style="cursor: zoom-in;">
/*
Coder: dummyz@126.com
*/
 
#include <Windows.h>
#include <fstream>
#include <memory>
#include <list>
#include <algorithm>
#include "xde.h"
 
using namespace std;
 
typedef unsigned char ubyte;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
 
ubyte* load_pefile(const char* fname, ulong& size)
{
    IMAGE_DOS_HEADER dosheader;
    IMAGE_NT_HEADERS ntheader;
    ifstream ifile(fname, ios::binary);
 
    if ( !ifile )
        return NULL;
 
    ifile.read((char*)&dosheader, sizeof (IMAGE_DOS_HEADER));
    if ( dosheader.e_magic != IMAGE_DOS_SIGNATURE )
        return NULL;
 
    ifile.seekg(dosheader.e_lfanew, ios::beg);
 
    ifile.read((char*)&ntheader, sizeof (IMAGE_NT_HEADERS));
    if ( ntheader.Signature != IMAGE_NT_SIGNATURE ||
        ntheader.FileHeader.NumberOfSections == 0 )
        return NULL;
 
    size = ifile.seekg(0, ios::end).tellg();
    ifile.seekg(0, ios::beg);
 
    auto_ptr<ubyte> buf(new ubyte[size]);
    ifile.read((char*)buf.get(), size);
 
    return buf.release();
}
 
typedef struct _instr
{
    ubyte* old_ip;
    ubyte* new_ip;
    xde_instr instr;
} instr_t;
 
bool is_hasip(list<instr_t>& instr_lst, ubyte* ip)
{
    list<instr_t>::iterator i = instr_lst.begin();
    while ( i != instr_lst.end() )
    {
        instr_t& p = *i++;
        if ( p.old_ip == ip )
        {
            return true;
        }
    }
 
    return false;
}
 
int main(int argc, char* argv[])
{
    if ( argc < 2 )
    {
        return -1;
    }
     
    ulong file_size;
    auto_ptr<ubyte> file_buf(load_pefile(argv[1], file_size));
    ubyte* base = file_buf.get();
    if ( base == NULL )
    {
        return -2;
    }
     
    list<instr_t> instr_lst; // 指令表
    list<ubyte*> ep_list; // 入口表
    instr_t instr;
 
    PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)base;
    PIMAGE_NT_HEADERS ntheader = (PIMAGE_NT_HEADERS)(base + dosheader->e_lfanew);
    PIMAGE_SECTION_HEADER sectheader = IMAGE_FIRST_SECTION(ntheader);
     
    ulong code_size = ntheader->OptionalHeader.SizeOfCode;
    ulong code_va = ntheader->OptionalHeader.ImageBase + sectheader->VirtualAddress;
    ulong oep_va = ntheader->OptionalHeader.ImageBase + ntheader->OptionalHeader.AddressOfEntryPoint;
 
    ubyte* code = base + sectheader->VirtualAddress;
 
    instr.old_ip = base + ntheader->OptionalHeader.AddressOfEntryPoint - \
        sectheader->VirtualAddress + sectheader->PointerToRawData;
     
    auto_ptr<byte> code_buf(new byte[code_size * 2]);
    memset(code_buf.get(), 0x90, code_size * 2);
 
    instr.new_ip = code_buf.get() + ntheader->OptionalHeader.AddressOfEntryPoint - \
        sectheader->VirtualAddress;
     
    // @1 重构串行指令序
    ep_list.push_back(instr.old_ip);
    while ( true )
    {
        list<ubyte*>::iterator it;
         
        printf("\r\bPasering eip = %08X...", instr.old_ip - code + code_va);
         
        if (
            instr.old_ip > code + code_size ||
            is_hasip(instr_lst, instr.old_ip) // 检查是否已经处理过了, 从入口表中取出新的地址
            )
        {
            if ( ep_list.empty() )
                break;
 
            instr.old_ip = ep_list.front();
            ep_list.erase(ep_list.begin());
        }
 
        if ( 0 == xde_disasm(instr.old_ip, &instr.instr) )
        {
            printf("xde_disasm error!\n");
            break;
        }
 
        /*
0040102C > $  C705 00104000>mov     dword ptr [401000], 00401333
00401036   .  FF25 00104000 jmp     dword ptr [401000]
        */
        if ( instr.instr.opcode == 0xc7 &&
            instr.instr.modrm == 0x05 &&
            (instr.instr.addr_l[0] >= code_va && instr.instr.addr_l[0] < oep_va)
            )
        {
            ubyte* next_ep_ip = instr.old_ip + instr.instr.len;
            if ( *(ushort*)next_ep_ip == 0x25ff &&
                *(ulong*)(next_ep_ip + 2) == instr.instr.addr_l[0]
                )
            {
                next_ep_ip += 6;
                if ( ep_list.end() == find(ep_list.begin(), ep_list.end(), next_ep_ip) &&
                    !is_hasip(instr_lst, next_ep_ip)
                    )
                {
                    ep_list.push_back(next_ep_ip);
                }
                 
                instr.old_ip = instr.instr.data_l[0] - code_va + code;
                continue;
            }
        }
 
        if ( instr.instr.flag & C_REL )
        {
            ubyte* next_ep_ip = instr.old_ip + instr.instr.len;
            switch ( instr.instr.datasize )
            {
            case 1: next_ep_ip = (ubyte*)((ulong)next_ep_ip + (long)instr.instr.data_c[0]); break;
            case 4: next_ep_ip = (ubyte*)((ulong)next_ep_ip + (long)instr.instr.data_l[0]); break;
            default: printf("error datasize!\n");  
            }
 
            if ( ep_list.end() == find(ep_list.begin(), ep_list.end(), next_ep_ip) &&
                !is_hasip(instr_lst, next_ep_ip)
                )
            {
                ep_list.push_back(next_ep_ip);
            }
 
            if ( instr.old_ip[0] == 0x8a )
            {
                instr.old_ip[0] = 0x8a;
            }
        }
         
        it = find(ep_list.begin(), ep_list.end(), instr.old_ip);
        if ( ep_list.end() != it ) // 从入口表中踢出
        {
            ep_list.erase(it);
        }
 
        instr_lst.push_back(instr);
        instr.new_ip += instr.instr.len;
 
        if ( instr.old_ip[0] == 0xc3 ||
            instr.old_ip[0] == 0xc2
            )
        {
            if ( ep_list.empty() )
                break;
 
            instr.old_ip = ep_list.front();
            ep_list.erase(ep_list.begin());
        }
        else
        {
            instr.old_ip += instr.instr.len;
        }
    }
     
    printf("\ninstr sum = %d\n", instr_lst.size());
     
    // @2 拷贝 & 校正偏移
    list<instr_t>::iterator instr_lst_i = instr_lst.begin();
    while ( instr_lst_i != instr_lst.end() )
    {
        instr_t& instr1 = *instr_lst_i++;
         
        printf("\r\bRelocing eip = %08X...", instr1.new_ip - code_buf.get() + code_va);
 
        if ( instr1.instr.flag & C_REL )
        {
            ubyte* jmp_ip = instr1.old_ip + instr1.instr.len;
            switch ( instr1.instr.datasize )
            {
            case 1: jmp_ip = (ubyte*)((ulong)jmp_ip + (long)instr1.instr.data_c[0]); break;
            case 4: jmp_ip = (ubyte*)((ulong)jmp_ip + (long)instr1.instr.data_l[0]); break;
            default: printf("error datasize!\n");
            }
             
            do
            {
                if ( jmp_ip[0] == 0xc7 && jmp_ip[1] == 0x05 &&
                    *(ulong*)(jmp_ip + 2) >= code_va && *(ulong*)(jmp_ip + 2) < oep_va
                    )
                {
                    if ( *(ushort*)(jmp_ip + 2 + 4 + 4) == 0x25ff &&
                        *(ulong*)(jmp_ip + 2 + 4 + 4 + 2) == *(ulong*)(jmp_ip + 2) )
                    {
                        jmp_ip = *(ulong*)(jmp_ip + 2 + 4) - code_va + code;
                        continue;
                    }
                }
 
                break;
            } while( true );
             
            list<instr_t>::iterator instr_lst_j = instr_lst.begin();
            while ( instr_lst_j != instr_lst.end() )
            {
                instr_t& instr2 = *instr_lst_j;
                if ( instr2.old_ip == jmp_ip )
                {
                    xde_instr tmp = instr1.instr;
 
                    tmp.data_l[0] = instr2.new_ip - instr1.new_ip + instr1.instr.len;
                    xde_asm(instr1.new_ip, &tmp); // 汇编
                    break;
                }
 
                instr_lst_j++;
            }
 
            if ( instr_lst_j == instr_lst.end() )
            {
                printf("reloc jmp error!\n");
                break;
            }
        }
        else
        {
            memcpy(instr1.new_ip, instr1.old_ip, instr1.instr.len);
        }
    }
     
    ofstream ofile("1.bin", ios::binary);
    ofile.write((char*)code_buf.get(), code_size);
     
    printf("\nFinished!\n");
 
    return 0;
}

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

上传的附件:
收藏
免费 7
支持
分享
赞赏记录
参与人
雪币
留言
时间
Youlor
为你点赞~
2024-1-3 00:17
伟叔叔
为你点赞~
2023-10-6 01:26
PLEBFE
为你点赞~
2023-7-14 00:03
QinBeast
为你点赞~
2023-7-11 00:25
shinratensei
为你点赞~
2023-6-18 01:30
心游尘世外
为你点赞~
2023-6-9 05:56
飘零丶
为你点赞~
2023-5-31 00:13
最新回复 (8)
雪    币: 7327
活跃值: (3813)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
2
学习+膜拜
先顶,再看什么壳
2008-1-15 20:03
0
雪    币: 817
活跃值: (1927)
能力值: ( LV12,RANK:2670 )
在线值:
发帖
回帖
粉丝
3
很暴力
2008-1-16 03:32
0
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
4
太黄了,我赶紧把窗口关了
2008-1-16 18:55
0
雪    币: 304
活跃值: (82)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
5
你这样很虚伪.
ps:直接被毒霸咔嚓了。
2008-1-17 11:55
0
雪    币: 1925
活跃值: (906)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
6
学习了~~~
2008-1-17 12:00
0
雪    币: 192
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
靠,没开杀毒,下来运行,没反应,再看中弹了,木马说一下啊
2008-1-17 16:19
0
雪    币: 272
活跃值: (143)
能力值: ( LV15,RANK:930 )
在线值:
发帖
回帖
粉丝
8

我....
2008-1-17 19:38
0
雪    币: 136
活跃值: (220)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
9
哈哈 中毒好啊 又将要有木马分析篇了
2008-1-18 20:52
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

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