学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

2万

积分

41

好友

1171

主题
发表于 2021-2-4 23:38:25 | 查看: 2443| 回复: 0

UPX对pe文件(x64)的加壳过程

UPX对pe文件(x64)的加壳过程

  • 压缩前
    1,将原pe文件按内存展开方式读入ibuf缓冲区,在区块数据后面拼接处理过的原导入表数数组oimport、重定位表orelocs等数据;
    2,清空区块数据中的调试目录Debug Directory、清空拷贝到oresources中的不压缩资源数据、重定位地址VA转换成相对rvamin的偏移并清空原重定位表;应该是为了提升压缩率
    3,自定义的导入表结构:

1
2
3
4
5
6
7
8
9
typedef struct _oimport{//要恢复的导入表数组oimport
    DWORD rva_dllname; // +00 dll名称在新资源表oresources中的rva 0表示结束
    DWORD rva_iat;     // +04 iat的rva
    //之后是函数数组
    BYTE type;         // +08 类型 1表示之后是dll函数名称 0xff之后函数序号     0xfe之后kernel32的函数名称rva 0表示当前dll不再有函数导入
    //根据不同的type之后可能是字符串、2字节的函数序号、4字节的rva
     
    //下一个dll
}

        4,自定义的重定位表,没有采用相对于每个块VirtualAddress的位移,而是使用相对前一个要处理的重定位地址的偏移

  • upx压缩

        1,Dos头、文件头原样输出,在头部最后添加了upx版本信息;
1
2
3
4
5
6
7
p->doPack(fo);
void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh,
                   unsigned subsystem_mask, upx_uint64_t default_imagebase,
                   bool last_section_rsrc_only)
                   readSectionHeaders(objs, sizeof(ih)); //读取节表 节表紧接在NtHeader之后
                   handleStub(fi,fo,pe_offset); //DosHeader、 DosStub等 NtHeader.OptionalHeader 之前的数据不做处理 直接输出
                   unsigned overlaystart = readSections(objs, ih.imagesize, ih.filealign, ih.datasize); //读入所有区块数据到ibuf

        2,将ibuf中从rvamin开始的数据压缩到obuf,保存到upx1开始的位置;
        3,紧接着的是壳代码loader,并作为新的oep;
        4,生成新线程局部存储otls;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void PeFile::processTls1(Interval *iv,
                         typename tls_traits<LEXX>::cb_value_t imagebase,
                         unsigned imagesize)
    //判断有多少个回调函数
    //保存重定位表中涉及tls的数据(在datastart与dataend之间)到临时结构tlsiv
    //如果原tls有回调函数,这里需要在otls最后预留2个位置用于存储回调函数tls_handler_offset和表示结束0填充回调函数
    //原tls目录整体保存到otls
    //将原TLS数据模板(datastart与dataend之间)的内容复制到ols
    //将原tls的AddressOfIndex字段设置为0
void PeFile::processTls2(Reloc *rel,const Interval *iv,unsigned newaddr,
                         typename tls_traits<LEXX>::cb_value_t imagebase)
    //x32需要修正rel->add(tls_handler_offset + tls_handler_offset_reloc, reloc_type); x64不需要。应该是跟tls_handler的代码有关(待验证)
    //因为tls使用的是VA不是RVA,将otls的前几个数据都加入到新的重定位表
    //将tlsiv中涉及的需要修改的重定位数据添加到新的重定位表
    //修正原tls的数据模板(datastart、dataend)的VA地址
    //如果原tls有回调,将tls_handler_offset和0填充到otls最后的位置,将otls的callbacks修正为指向otls中tls_handler_offset正确的VA
    //因为tls使用的是VA不是RVA,将修正后的VA都要加入的新的重定位表

        5,生成新资源表oresources(程序默认图标等资源不能压缩);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void PeFile::processResources(Resource *res)//处理资源
    res->init(ibuf.subref("bad res %#x", vaddr, 1));
    start = res;
    root = head = current = NULL;//root指向根节点 head用于串联叶子节点 current用于遍历叶子节点
    dsize = ssize = 0;//dsize记录所有1-4级节点数据长度 ssize记录涉及到的unicode strings字符串占用长度
    root = convert(start,NULL,0);//从数组的最后1个元素向前遍历,所以head指向第一个叶子节点
    for (soresources = res->dirsize(); res->next(); soresources += 4 + res->size()); //遍历所有叶子节点取资源[size+4(保存资源数据的原始RAV)]+dsize+ssize 一起赋值给soresources(即soresources为所有资源数据总长度)
    if (opt->win32_pe.compress_icons == 2)
        //取出第一个有图标的图标组中所有图标的id 格式3/id,(如"3/1,3/2,3/3,3/4")
    //遍历所有叶子节点
        //刚刚取出的第一个有图标的图标组及其下id对应的图标不压缩 其他的图标组及图标都压缩
        //0x10  版本信息 RT_VERSION 不压缩
        //0x18  MANIFEST元数据文件 不压缩
        //将不压缩的资源数据拷贝到ores中,清空其在ibuf中的数据
    //设置soresources为 未压缩资源[size+4(保存资源数据的原始RAV)]+dsize+ssize
void PeFile::callProcessResources(Resource &res, unsigned &ic)
    void PeFile::processResources(Resource *res,unsigned newaddr)
        //遍历叶子节点 将newoffset加上新的根元素地址
        upx_byte *p = res->build();//构建新的资源目录项
            build(root,bpos,spos,0);//bpos存储节点数据的偏移 spos存储涉及到的unicode strings字符串的偏移
        //将新的资源目录项拷贝到oresources的开始位置
    //设置新资源目录表的RVA和size  soresources为size

        6,生成新导入表oimpdlls;
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
const unsigned dllstrings = processImports(); //处理导入表
//不理解"*UND*"、 "*ZSTART" 等section的作用? (size为0)
    unsigned PeFile::processImports0(ord_mask_t ord_mask)
    //获取导入表涉及多少个dll
    //对dll进行排序
    ilinker = new ImportLinker(sizeof(LEXX)); //*UND* *ZSTART Dzero Zzero
    //addStubImports(); //将kernel32的 LoadLibraryA GetProcAddress ExitProcess VirtualProtect 添加到导入表
    //每个dll取1个函数 添加到导入表到ilinker (kernel32使用ordinals引入的全部添加)
    soimpdlls = ilinker->build();//soimpdlls新导入表长度 建立的output用来存储新的导入表数据
        qsort(sections, nsections, sizeof (Section*), ImportLinker::compare);   //排序
        addLoader(sections[ic]->name);   //将section->input复制到output 设置section的offset字段 使用next串联section
        //Dgbgehggbhagjdddccogegmgm advapi32.dll size:20
        //Dgdgpgngdhegmdddccogegmgm comctl32.dll
        //...
        //Dhfhdgfhcdddccogegmgm user32.dll
        //Dhfhihegigfgngfcogegmgm uxtheme.dll
        //Dzero
        //EgbgehggbhagjdddccogegmgmIfcgfghedgmgphdgfelgfhj advapi32.dll RegCloseKey size:8
        //EgbgehggbhagjdddccogegmgmKfi advapi32.dll X //X相当于填充0
        //EgdgpgngdhegmdddccogegmgmIejgngbghgfemgjhdhefpeehcgbhh comctl32.dll ImageList_Draw
        //EgdgpgngdhegmdddccogegmgmKfi comctl32.dll X
        //...
        //EhfhihegigfgngfcogegmgmIejhdebhahafegigfgngfge uxtheme.dll IsAppThemed
        //EhfhihegigfgngfcogegmgmKfi uxtheme.dll X
        //Fgbgehggbhagjdddccogegmgm advapi32.dll size:dll名称长度+1
        //Fgdgpgngdhegmdddccogegmgm comctl32.dll
        //...
        //Fhfhihegigfgngfcogegmgm uxtheme.dll
        //GgbgehggbhagjdddccogegmgmLfcgfghedgmgphdgfelgfhj advapi32.dll RegCloseKey size:2
        //GgbgehggbhagjdddccogegmgmLfcgfghedgmgphdgfelgfhjX size:11
        //...
        //Zzero
void PeFile::processImports2(unsigned myimport, unsigned)
    ilinker->relocate_import(myimport);
    oimpdlls = ilinker->getLoader(&len);//新的导入表 len返回新导入表长度 output赋值给oimpdlls

  • 执行壳代码loader

        1,将obuf中的数据解压到从upx0开始的位置;
        2,根据解压后oimport的数据使用kernel32中的LoadLibraryA和GetProcAddress初始化原iat;
        3,根据orelocs修正重定位数据;
        4,去除upx0、upx1区段的可写属性;
        5,跳转到真实oep继续执行
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
UPX1:000000013FE23B20                 public start
UPX1:000000013FE23B20 start           proc near
UPX1:000000013FE23B20                 push    rbx
UPX1:000000013FE23B21                 push    rsi
UPX1:000000013FE23B22                 push    rdi
UPX1:000000013FE23B23                 push    rbp
UPX1:000000013FE23B24                 lea     rsi, upx1_obuf  ; rsi指向upx1的VA 即压缩后的数据obuf
UPX1:000000013FE23B2B                 lea     rdi, [rsi-0AAC000h] ; rdi指向upx0的VA
UPX1:000000013FE23B32                 push    rdi
UPX1:000000013FE23B33                 xor     ebx, ebx
UPX1:000000013FE23B35                 xor     ecx, ecx
UPX1:000000013FE23B37                 or      rbp, 0FFFFFFFFFFFFFFFFh
UPX1:000000013FE23B3B                 call    loader_stub     ; 栈参数rdi指向upx0的VA
UPX1:000000013FE23B3B start           endp ; sp-analysis failed ; 寄存器
UPX1:000000013FE23B3B                                         ; ebx=0
UPX1:000000013FE23B3B                                         ; ecx=0
UPX1:000000013FE23B3B                                         ; rsi指向upx1的VA 即压缩后的数据obuf
UPX1:000000013FE23B3B                                         ; cld让方向标志位DF=0,std让DF=1
UPX1:000000013FE23B40
UPX1:000000013FE23B40 ; =============== S U B R O U T I N E =======================================
UPX1:000000013FE23B40
UPX1:000000013FE23B40 ; ebx左移1位如果为0
UPX1:000000013FE23B40 ;  取esi处的Dword给ebx
UPX1:000000013FE23B40 ;  rsi减-4
UPX1:000000013FE23B40 ;  ebx带进位左移1位
UPX1:000000013FE23B40 ;  从rsi处取1个字节给dl
UPX1:000000013FE23B40
UPX1:000000013FE23B40 get_ebx2_if0_rsi4ebx_rsi5dl proc near
UPX1:000000013FE23B40                 add     ebx, ebx
UPX1:000000013FE23B42                 jz      short loc_13FE23B46
UPX1:000000013FE23B44                 rep retn
UPX1:000000013FE23B46 ; ---------------------------------------------------------------------------
UPX1:000000013FE23B46
UPX1:000000013FE23B46 loc_13FE23B46:                          ; CODE XREF: get_ebx2_if0_rsi4ebx_rsi5dl+2↑j
UPX1:000000013FE23B46                 mov     ebx, [rsi]
UPX1:000000013FE23B48                 sub     rsi, 0FFFFFFFFFFFFFFFCh
UPX1:000000013FE23B4C                 adc     ebx, ebx
UPX1:000000013FE23B4E                 mov     dl, [rsi]
UPX1:000000013FE23B50                 rep retn
UPX1:000000013FE23B50 get_ebx2_if0_rsi4ebx_rsi5dl endp
UPX1:000000013FE23B50
UPX1:000000013FE23B52
UPX1:000000013FE23B52 ; =============== S U B R O U T I N E =======================================
UPX1:000000013FE23B52
UPX1:000000013FE23B52 ; 从rdi+rbp处开始复制ecx个字节到rdi处
UPX1:000000013FE23B52
UPX1:000000013FE23B52 copy2_rdi_from_rdirbp_ecx proc near     ; CODE XREF: loader_stub+A3↓p
UPX1:000000013FE23B52                 lea     rax, [rdi+rbp]
UPX1:000000013FE23B56                 cmp     ecx, 5
UPX1:000000013FE23B59                 mov     dl, [rax]
UPX1:000000013FE23B5B                 jbe     short loc_13FE23B7E
UPX1:000000013FE23B5D                 cmp     rbp, 0FFFFFFFFFFFFFFFCh
UPX1:000000013FE23B61                 ja      short loc_13FE23B7E
UPX1:000000013FE23B63                 sub     ecx, 4
UPX1:000000013FE23B66
UPX1:000000013FE23B66 loc_13FE23B66:                          ; CODE XREF: copy2_rdi_from_rdirbp_ecx+23↓j
UPX1:000000013FE23B66                 mov     edx, [rax]
UPX1:000000013FE23B68                 add     rax, 4
UPX1:000000013FE23B6C                 sub     ecx, 4
UPX1:000000013FE23B6F                 mov     [rdi], edx
UPX1:000000013FE23B71                 lea     rdi, [rdi+4]
UPX1:000000013FE23B75                 jnb     short loc_13FE23B66
UPX1:000000013FE23B77                 add     ecx, 4
UPX1:000000013FE23B7A                 mov     dl, [rax]
UPX1:000000013FE23B7C                 jz      short locret_13FE23B8E
UPX1:000000013FE23B7E
UPX1:000000013FE23B7E loc_13FE23B7E:                          ; CODE XREF: copy2_rdi_from_rdirbp_ecx+9↑j
UPX1:000000013FE23B7E                                         ; copy2_rdi_from_rdirbp_ecx+F↑j ...
UPX1:000000013FE23B7E                 inc     rax
UPX1:000000013FE23B81                 mov     [rdi], dl
UPX1:000000013FE23B83                 sub     ecx, 1
UPX1:000000013FE23B86                 mov     dl, [rax]
UPX1:000000013FE23B88                 lea     rdi, [rdi+1]
UPX1:000000013FE23B8C                 jnz     short loc_13FE23B7E
UPX1:000000013FE23B8E
UPX1:000000013FE23B8E locret_13FE23B8E:                       ; CODE XREF: copy2_rdi_from_rdirbp_ecx+2A↑j
UPX1:000000013FE23B8E                 rep retn
UPX1:000000013FE23B8E copy2_rdi_from_rdirbp_ecx endp
UPX1:000000013FE23B8E
UPX1:000000013FE23B90
UPX1:000000013FE23B90 ; =============== S U B R O U T I N E =======================================
UPX1:000000013FE23B90
UPX1:000000013FE23B90 ; 栈参数rdi指向upx0的VA
UPX1:000000013FE23B90 ; 寄存器
UPX1:000000013FE23B90 ; ebx=0
UPX1:000000013FE23B90 ; ecx=0
UPX1:000000013FE23B90 ; rsi指向upx1的VA 即压缩后的数据obuf
UPX1:000000013FE23B90
UPX1:000000013FE23B90 loader_stub     proc near               ; CODE XREF: start+1B↑p
UPX1:000000013FE23B90
UPX1:000000013FE23B90 var_50          = byte ptr -50h
UPX1:000000013FE23B90 arg_0           = byte ptr  8
UPX1:000000013FE23B90
UPX1:000000013FE23B90 get_ebx2_if0_rsi4ebx_rsi5dl = r11
UPX1:000000013FE23B90                 cld
UPX1:000000013FE23B91                 pop     get_ebx2_if0_rsi4ebx_rsi5dl ; 返回地址 0x140053B40
UPX1:000000013FE23B93                 jmp     short loc_13FE23B9D
UPX1:000000013FE23B95 ; ---------------------------------------------------------------------------
UPX1:000000013FE23B95
UPX1:000000013FE23B95 loc_13FE23B95:                          ; CODE XREF: loader_stub:loc_13FE23BAD↓j
UPX1:000000013FE23B95                 inc     rsi
UPX1:000000013FE23B98                 mov     [rdi], dl       ; 复制dl中的1字节数据到rdi指向的upx0
UPX1:000000013FE23B9A                 inc     rdi             ; rsi、rdi指向下一个待处理数据
UPX1:000000013FE23B9D
UPX1:000000013FE23B9D loc_13FE23B9D:                          ; CODE XREF: loader_stub+3↑j
UPX1:000000013FE23B9D                                         ; loader_stub+A8↓j
UPX1:000000013FE23B9D                 mov     dl, [rsi]
UPX1:000000013FE23B9F                 add     ebx, ebx        ; 如果ebx不是0,从rsi处取1字节到dl,ebx左移1位
UPX1:000000013FE23BA1                 jnz     short loc_13FE23BAD ; ebx不是0跳转
UPX1:000000013FE23BA3                 mov     ebx, [rsi]      ; 如果ebx是0,重新从rsi处取Dword到ebx
UPX1:000000013FE23BA5                 sub     rsi, 0FFFFFFFFFFFFFFFCh ; rsi减-4
UPX1:000000013FE23BA9                 adc     ebx, ebx        ; ebx带进位左移1位
UPX1:000000013FE23BAB                 mov     dl, [rsi]       ; 从rsi处取1字节到dl
UPX1:000000013FE23BAD
UPX1:000000013FE23BAD loc_13FE23BAD:                          ; CODE XREF: loader_stub+11↑j
UPX1:000000013FE23BAD                 jb      short loc_13FE23B95 ; 判断CF进位标志位,为1时跳转
UPX1:000000013FE23BAF                 lea     eax, [rcx+1]
UPX1:000000013FE23BB2                 jmp     short loc_13FE23BBB
UPX1:000000013FE23BB4 ; ---------------------------------------------------------------------------
UPX1:000000013FE23BB4
UPX1:000000013FE23BB4 loc_13FE23BB4:                          ; CODE XREF: loader_stub:loc_13FE23BCE↓j
UPX1:000000013FE23BB4                 dec     eax
UPX1:000000013FE23BB6                 call    get_ebx2_if0_rsi4ebx_rsi5dl
UPX1:000000013FE23BB9                 adc     eax, eax
UPX1:000000013FE23BBB
UPX1:000000013FE23BBB loc_13FE23BBB:                          ; CODE XREF: loader_stub+22↑j
UPX1:000000013FE23BBB                 call    get_ebx2_if0_rsi4ebx_rsi5dl
UPX1:000000013FE23BBE                 adc     eax, eax
UPX1:000000013FE23BC0                 add     ebx, ebx
UPX1:000000013FE23BC2                 jnz     short loc_13FE23BCE
UPX1:000000013FE23BC4                 mov     ebx, [rsi]
UPX1:000000013FE23BC6                 sub     rsi, 0FFFFFFFFFFFFFFFCh
UPX1:000000013FE23BCA                 adc     ebx, ebx
UPX1:000000013FE23BCC                 mov     dl, [rsi]
UPX1:000000013FE23BCE
UPX1:000000013FE23BCE loc_13FE23BCE:                          ; CODE XREF: loader_stub+32↑j
UPX1:000000013FE23BCE                 jnb     short loc_13FE23BB4
UPX1:000000013FE23BD0                 sub     eax, 3
UPX1:000000013FE23BD3                 jb      short loc_13FE23BEE
UPX1:000000013FE23BD5                 shl     eax, 8
UPX1:000000013FE23BD8                 movzx   edx, dl
UPX1:000000013FE23BDB                 or      eax, edx
UPX1:000000013FE23BDD                 inc     rsi
UPX1:000000013FE23BE0                 xor     eax, 0FFFFFFFFh
UPX1:000000013FE23BE3                 jz      short loc_13FE23C3D ; 区块数据解压完成,准备开始处理导入表、重定位表等
UPX1:000000013FE23BE5                 sar     eax, 1
UPX1:000000013FE23BE7                 movsxd  rbp, eax
UPX1:000000013FE23BEA                 jb      short loc_13FE23C24
UPX1:000000013FE23BEC                 jmp     short loc_13FE23BFC
UPX1:000000013FE23BEE ; ---------------------------------------------------------------------------
UPX1:000000013FE23BEE
UPX1:000000013FE23BEE loc_13FE23BEE:                          ; CODE XREF: loader_stub+43↑j
UPX1:000000013FE23BEE                 add     ebx, ebx
UPX1:000000013FE23BF0                 jnz     short loc_13FE23BFA
UPX1:000000013FE23BF2                 mov     ebx, [rsi]
UPX1:000000013FE23BF4                 sub     rsi, 0FFFFFFFFFFFFFFFCh
UPX1:000000013FE23BF8                 adc     ebx, ebx
UPX1:000000013FE23BFA
UPX1:000000013FE23BFA loc_13FE23BFA:                          ; CODE XREF: loader_stub+60↑j
UPX1:000000013FE23BFA                 jb      short loc_13FE23C24
UPX1:000000013FE23BFC
UPX1:000000013FE23BFC loc_13FE23BFC:                          ; CODE XREF: loader_stub+5C↑j
UPX1:000000013FE23BFC                 inc     ecx
UPX1:000000013FE23BFE                 add     ebx, ebx
UPX1:000000013FE23C00                 jnz     short loc_13FE23C0A
UPX1:000000013FE23C02                 mov     ebx, [rsi]
UPX1:000000013FE23C04                 sub     rsi, 0FFFFFFFFFFFFFFFCh
UPX1:000000013FE23C08                 adc     ebx, ebx
UPX1:000000013FE23C0A
UPX1:000000013FE23C0A loc_13FE23C0A:                          ; CODE XREF: loader_stub+70↑j
UPX1:000000013FE23C0A                 jb      short loc_13FE23C24
UPX1:000000013FE23C0C
UPX1:000000013FE23C0C loc_13FE23C0C:                          ; CODE XREF: loader_stub:loc_13FE23C1D↓j
UPX1:000000013FE23C0C                 call    get_ebx2_if0_rsi4ebx_rsi5dl
UPX1:000000013FE23C0F                 adc     ecx, ecx
UPX1:000000013FE23C11                 add     ebx, ebx
UPX1:000000013FE23C13                 jnz     short loc_13FE23C1D
UPX1:000000013FE23C15                 mov     ebx, [rsi]
UPX1:000000013FE23C17                 sub     rsi, 0FFFFFFFFFFFFFFFCh
UPX1:000000013FE23C1B                 adc     ebx, ebx
UPX1:000000013FE23C1D
UPX1:000000013FE23C1D loc_13FE23C1D:                          ; CODE XREF: loader_stub+83↑j
UPX1:000000013FE23C1D                 jnb     short loc_13FE23C0C
UPX1:000000013FE23C1F                 add     ecx, 2
UPX1:000000013FE23C22                 jmp     short loc_13FE23C29
UPX1:000000013FE23C24 ; ---------------------------------------------------------------------------
UPX1:000000013FE23C24
UPX1:000000013FE23C24 loc_13FE23C24:                          ; CODE XREF: loader_stub+5A↑j
UPX1:000000013FE23C24                                         ; loader_stub:loc_13FE23BFA↑j ...
UPX1:000000013FE23C24                 call    get_ebx2_if0_rsi4ebx_rsi5dl
UPX1:000000013FE23C27                 adc     ecx, ecx
UPX1:000000013FE23C29
UPX1:000000013FE23C29 loc_13FE23C29:                          ; CODE XREF: loader_stub+92↑j
UPX1:000000013FE23C29                 cmp     rbp, 0FFFFFFFFFFFFFB00h
UPX1:000000013FE23C30                 adc     ecx, 2
UPX1:000000013FE23C33                 call    copy2_rdi_from_rdirbp_ecx ; 从rdi+rbp处开始复制ecx个字节到rdi处
UPX1:000000013FE23C38                 jmp     loc_13FE23B9D
UPX1:000000013FE23C3D ; ---------------------------------------------------------------------------
UPX1:000000013FE23C3D
UPX1:000000013FE23C3D loc_13FE23C3D:                          ; CODE XREF: loader_stub+53↑j
UPX1:000000013FE23C3D                 pop     rsi
UPX1:000000013FE23C3E                 sub     rsp, 28h
UPX1:000000013FE23C42                 lea     rdi, [rsi+0C3C000h] ; rdi指向要恢复的导入表数组oimport
UPX1:000000013FE23C49
UPX1:000000013FE23C49 loc_13FE23C49:                          ; CODE XREF: loader_stub+E0↓j
UPX1:000000013FE23C49                 mov     eax, [rdi]      ; dll名称rva,0表示dll结束
UPX1:000000013FE23C4B                 or      eax, eax
UPX1:000000013FE23C4D                 jz      short loc_13FE23CA5 ; 完成原exe的iat的初始化
UPX1:000000013FE23C4F                 mov     ebx, [rdi+4]    ; iat的rva
UPX1:000000013FE23C52                 lea     rcx, [rax+rsi+0C5BBE4h] ; 获得dll名称
UPX1:000000013FE23C5A                 add     rbx, rsi        ; iat的va
UPX1:000000013FE23C5D                 add     rdi, 8
UPX1:000000013FE23C61                 call    large qword ptr cs:13FE2CD38h ; kernel32_LoadLibraryA
UPX1:000000013FE23C67                 xchg    rax, rbp        ; 将dll句柄保存到rbp
UPX1:000000013FE23C69
UPX1:000000013FE23C69 loc_13FE23C69:                          ; CODE XREF: loader_stub+10D↓j
UPX1:000000013FE23C69                 mov     al, [rdi]       ; 取之后函数的类型
UPX1:000000013FE23C69                                         ; 1表示之后是dll函数名称
UPX1:000000013FE23C69                                         ; 0xff之后函数序号
UPX1:000000013FE23C69                                         ; 0xfe之后kernel32的函数名称rva
UPX1:000000013FE23C6B                 inc     rdi
UPX1:000000013FE23C6E                 or      al, al
UPX1:000000013FE23C70                 jz      short loc_13FE23C49 ; 类型为0,表示函数结束
UPX1:000000013FE23C72                 jns     short loc_13FE23C7E
UPX1:000000013FE23C74                 movzx   rdx, word ptr [rdi] ; rdx=函数序号
UPX1:000000013FE23C78                 add     rdi, 2
UPX1:000000013FE23C7C                 jmp     short loc_13FE23C88 ; rcx=dll句柄
UPX1:000000013FE23C7E ; ---------------------------------------------------------------------------
UPX1:000000013FE23C7E
UPX1:000000013FE23C7E loc_13FE23C7E:                          ; CODE XREF: loader_stub+E2↑j
UPX1:000000013FE23C7E                 mov     rcx, rdi
UPX1:000000013FE23C81                 mov     rdx, rdi
UPX1:000000013FE23C84                 dec     eax
UPX1:000000013FE23C86                 repne scasb             ; rdx=函数名称
UPX1:000000013FE23C88
UPX1:000000013FE23C88 loc_13FE23C88:                          ; CODE XREF: loader_stub+EC↑j
UPX1:000000013FE23C88                 mov     rcx, rbp        ; rcx=dll句柄
UPX1:000000013FE23C8B                 call    large qword ptr cs:13FE2CD48h ; kernel32_GetProcAddress
UPX1:000000013FE23C91                 or      rax, rax        ; 函数地址
UPX1:000000013FE23C94                 jz      short loc_13FE23C9F ; 获取函数地址失败,则程序退出
UPX1:000000013FE23C96                 mov     [rbx], rax      ; 保存iat
UPX1:000000013FE23C99                 add     rbx, 8
UPX1:000000013FE23C9D                 jmp     short loc_13FE23C69 ; 取之后函数的类型
UPX1:000000013FE23C9D                                         ; 1表示之后是dll函数名称
UPX1:000000013FE23C9D                                         ; 0xff之后函数序号
UPX1:000000013FE23C9D                                         ; 0xfe之后kernel32的函数名称rva
UPX1:000000013FE23C9F ; ---------------------------------------------------------------------------
UPX1:000000013FE23C9F
UPX1:000000013FE23C9F loc_13FE23C9F:                          ; CODE XREF: loader_stub+104↑j
UPX1:000000013FE23C9F                 jmp     large qword ptr cs:13FE2CD40h ; ntdll_RtlExitUserProcess
UPX1:000000013FE23CA5 ; ---------------------------------------------------------------------------
UPX1:000000013FE23CA5
UPX1:000000013FE23CA5 loc_13FE23CA5:                          ; CODE XREF: loader_stub+BD↑j
UPX1:000000013FE23CA5                 add     rsp, 28h
UPX1:000000013FE23CA9                 add     rdi, 4          ; rdi指向处理后的原重定位表orelocs
UPX1:000000013FE23CAD                 lea     rbx, [rsi-4]    ; rbx是重定位基址,指向upx0-4
UPX1:000000013FE23CB1
UPX1:000000013FE23CB1 loc_13FE23CB1:                          ; CODE XREF: loader_stub+13F↓j
UPX1:000000013FE23CB1                 xor     eax, eax
UPX1:000000013FE23CB3                 mov     al, [rdi]       ; 取1字节的oc
UPX1:000000013FE23CB5                 inc     rdi
UPX1:000000013FE23CB8                 or      eax, eax
UPX1:000000013FE23CBA                 jz      short loc_13FE23CE9 ; 0表示处理结束
UPX1:000000013FE23CBC                 cmp     al, 0EFh
UPX1:000000013FE23CBE                 ja      short loc_13FE23CD1 ; oc>=0xF0
UPX1:000000013FE23CC0
UPX1:000000013FE23CC0 loc_13FE23CC0:                          ; CODE XREF: loader_stub+14F↓j
UPX1:000000013FE23CC0                                         ; loader_stub+157↓j
UPX1:000000013FE23CC0                 add     rbx, rax        ; rax是相对偏移,rbx为当前需要修复的重定位va
UPX1:000000013FE23CC3                 mov     rax, [rbx]
UPX1:000000013FE23CC6                 bswap   rax
UPX1:000000013FE23CC9                 add     rax, rsi        ; rax转化成va
UPX1:000000013FE23CCC                 mov     [rbx], rax
UPX1:000000013FE23CCF                 jmp     short loc_13FE23CB1
UPX1:000000013FE23CD1 ; ---------------------------------------------------------------------------
UPX1:000000013FE23CD1
UPX1:000000013FE23CD1 loc_13FE23CD1:                          ; CODE XREF: loader_stub+12E↑j
UPX1:000000013FE23CD1                 and     al, 0Fh         ; oc>=0xF0
UPX1:000000013FE23CD3                 shl     eax, 10h
UPX1:000000013FE23CD6                 mov     ax, [rdi]       ; 再取2字节
UPX1:000000013FE23CD9                 add     rdi, 2
UPX1:000000013FE23CDD                 or      eax, eax
UPX1:000000013FE23CDF                 jnz     short loc_13FE23CC0 ; rax是相对偏移,rbx为当前需要修复的重定位va
UPX1:000000013FE23CE1                 mov     eax, [rdi]      ; 刚取的2字节为0,说明后4字节为真实偏移
UPX1:000000013FE23CE3                 add     rdi, 4
UPX1:000000013FE23CE7                 jmp     short loc_13FE23CC0 ; rax是相对偏移,rbx为当前需要修复的重定位va
UPX1:000000013FE23CE9 ; ---------------------------------------------------------------------------
UPX1:000000013FE23CE9
UPX1:000000013FE23CE9 loc_13FE23CE9:                          ; CODE XREF: loader_stub+12A↑j
UPX1:000000013FE23CE9                 mov     rbp, large cs:13FE2CD50h ; kernel32_VirtualProtect
UPX1:000000013FE23CF0                 lea     rdi, [rsi-1000h]
UPX1:000000013FE23CF7                 mov     ebx, 1000h
UPX1:000000013FE23CFC                 push    rax
UPX1:000000013FE23CFD                 mov     r9, rsp         ; 保存原保护方式
UPX1:000000013FE23D00                 mov     r8d, 4          ; 保护方式 4 PAGE_READWRITE
UPX1:000000013FE23D06                 mov     rdx, rbx        ; 大小
UPX1:000000013FE23D09                 mov     rcx, rdi        ; 起始地址
UPX1:000000013FE23D0C                 sub     rsp, 20h
UPX1:000000013FE23D10                 call    rbp             ; kernel32_VirtualProtect
UPX1:000000013FE23D12                 lea     rax, [rdi+247h]
UPX1:000000013FE23D19                 and     byte ptr [rax], 7Fh ; 去除upx0区段的可写属性
UPX1:000000013FE23D1C                 and     byte ptr [rax+28h], 7Fh ; 去除upx1区段的可写属性
UPX1:000000013FE23D20                 lea     r9, [rsp+18h+arg_0]
UPX1:000000013FE23D25                 mov     r8, [r9]        ; 恢复原保护方式
UPX1:000000013FE23D28                 mov     rdx, rbx
UPX1:000000013FE23D2B                 mov     rcx, rdi
UPX1:000000013FE23D2E                 call    rbp             ; kernel32_VirtualProtect
UPX1:000000013FE23D30                 add     rsp, 28h
UPX1:000000013FE23D34                 pop     rbp
UPX1:000000013FE23D35                 pop     rdi
UPX1:000000013FE23D36                 pop     rsi
UPX1:000000013FE23D37                 pop     rbx
UPX1:000000013FE23D38                 lea     rax, [rsp-30h+var_50]
UPX1:000000013FE23D3D
UPX1:000000013FE23D3D loc_13FE23D3D:                          ; CODE XREF: loader_stub+1B2↓j
UPX1:000000013FE23D3D                 push    0               ; 平衡栈
UPX1:000000013FE23D3F                 cmp     rsp, rax
UPX1:000000013FE23D42                 jnz     short loc_13FE23D3D ; 平衡栈
UPX1:000000013FE23D44                 sub     rsp, 0FFFFFFFFFFFFFF80h
UPX1:000000013FE23D48                 jmp     oep_real         ; 壳代码执行完毕,跳转到原oep继续执行
UPX1:000000013FE23D48 loader_stub     endp ; sp-analysis failed

温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
论坛交流群:672619046

小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

GMT+8, 2024-12-27 19:53 , Processed in 0.393244 second(s), 38 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表