
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的位移,而是使用相对前一个要处理的重定位地址的偏移
1,Dos头、文件头原样输出,在头部最后添加了upx版本信息;
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;
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(程序默认图标等资源不能压缩);
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;
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
1,将obuf中的数据解压到从upx0开始的位置;
2,根据解压后oimport的数据使用kernel32中的LoadLibraryA和GetProcAddress初始化原iat;
3,根据orelocs修正重定位数据;
4,去除upx0、upx1区段的可写属性;
5,跳转到真实oep继续执行
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
安卓应用层抓包通杀脚本发布!《高研班》2021年6月班开始招生!
最后于 2021-1-31 11:54
被kobsky编辑
,原因: