常见魔改UPX
几篇大佬的文章:
https://cujo.com/blog/upx-anti-unpacking-techniques-in-iot-malware/
https://www.cnblogs.com/ichunqiu/p/7245329.html
https://bbs.kanxue.com/thread-275753.htm
https://www.52pojie.cn/forum.php?mod=viewthread&tid=326995
Header Structures



p_filesize
-
图一的p_filesize可以全部修改成0(图三也有p_filesize)
-
example [susctf mirai]
可以看到p_info中的p_filesize为0(addr:0x00F4)

找到第二段p_size位置有值,将0x2878的值放到0x00F4处即可-d解密.

overlay_offset
-
overlay_offset位于文件尾部,是p_info的偏移值,当修改overlay_offset时直接-d会报错l_info(逆天,我感觉是p_info来着)
-
example [basectf UPX PRO]
直接打开overlay_offset是

找到p_info的位置,为0xF4

将overlay_offset改为0xF4即可直接-d解密.
magic on linux
- linux也可以魔改upx!,将FUK?改为UPX!即可

手脱upx on linux
- upx加壳后很多时候会导致exe变为dyn类型,欺骗ida进行调试的方法如下:
- 将原程序用010改为exe,用ida打开该程序.
- 在debuger option中选择调试原程序(dyn).
- 在此处下读写断点

- 调式,大概第三次断下来的时候,在rdi中有下面的情况

- 将qword_45B0E8数组未定义一下,得到下面结果

- 进入unk_45C080,下执行断点,并取消第一次下的断点,执行,断下的结果的形式不止一种,仅作参考

- 执行dump_elf.py,终端输入dump_elf(base_addr),即可得到dump.bin文件.
- dump_elf已知问题解决: 见实例
实例:encsh程序(自改UPX+反调试)
-
upx加壳后很多时候会导致exe变为dyn类型,欺骗ida进行调试的方法如下:
- 将原程序用010改为exe,用ida打开该程序.
- 在debuger option中选择调试原程序(dyn).
-
因为运行发现有反调试,调用strace查看是否有调用ptrace()
strace ./encsh -
确定存在后,可以用pwndbg确认位置.并且由于反调试在upx解压缩的过程中,需要先等upx自己mmap出来prace()的内存
gdb encsh catch syscall mprotect catch syscall ptrace vmmap //确定base_addr r //运行到断点 c //continue- 之后找到mprotect的地址,在他后面下断点,之后运行到此位置后就可以进入ptrace()的地址,之后c出来syscall的代码,下断点rax == 0x65,之后运行,将rax置0,即可绕过反调试
- mprotect的地址是动态的
- ptrace()的地址不是....
- .....我也不知道为什么
- 之后在入口点下断点,run,之后确定循环解压位置(只看write的部分,32位一直写,等到出现一个确定的地址,而64位好像是以偏移显示),等走出循环,回到入口点,即可进入OEP,在此处下执行断点,将入口点的断点disable,再次断住,就是OEP,之后运行脚本dump_elf
- 之后找到mprotect的地址,在他后面下断点,之后运行到此位置后就可以进入ptrace()的地址,之后c出来syscall的代码,下断点rax == 0x65,之后运行,将rax置0,即可绕过反调试
-
得到dump.bin后,放入ida,找到ELF Dynamic Information,将此处代码u掉,之后运行脚本,将大于原先base_addr的部分减去原base_addr(脚本已经修复此处)
-
对于.got.plt section的部分需要手动清零,对应位置如下(或者直接找到.got节也可以)
-
需要修的程序对应的位置(貌似是start函数的最后一个参数):

-
正常程序对应的位置:

-
将下面两处值清零:

-

浙公网安备 33010602011771号