BabyRe
tips:
_initterm, _initterm_e
atexit:简单来说,就是程序正常退出之前,会调用atexit注册的函数,调用顺序是栈式的,即先注册后调用。
函数调用顺序:sub_401000(初始化,注册sub_405770) -> sub_401170(初始化,检查输入全为数字) -> sub_401050(调用sub_401230,注册sub_4057B0) -> sub_401230(处理后续使用的表) -> sub_4010A0(调用hook函数,注册sub_4057F0) -> sub_4012B0(将GetLastError函数hook为sub_4019D0,此函数修改了哈希常量) -> sub_401670(调用base加密并cmp) -> sub_4015C0(调用hash并cmp) -> sub_405770(RC4并cmp,最终输出结果)
整个加密流程为:将输入base8编码,然后取[16:112]
与密文对比(即前6字节和后面的不可知),base8后的前16字节哈希后与密文对比,最后取输入的最后6字节作为RC4密钥加密[:112]
可以根据RC4爆破6字节密钥,获得base8后的密文
1 |
|
对输出base8解码,打表或者直接逆都可以,得到明文561516915572239428449843076691286116796614
,再接上key,得到561516915572239428449843076691286116796614807391
,即为flag。
Berkeley
ebpf程序
strings得源码(在1.8k+行的地方):
1 | for(int i=0; i<256; i++) |
逆向得exp:
1 | key = [0xC1, 0xD1, 0x02, 0x61, 0xD6, 0xF7, 0x13, 0xA2, 0x9B, 0x20, 0xD0, 0x4A, 0x8F, 0x7F, 0xEE, 0xB9, 0x00, 0x63, 0x34, 0xB0, 0x33, 0xB7, 0x8A, 0x8B, 0x94, 0x60, 0x2E, 0x8E, 0x21, 0xFF, 0x90, 0x82, 0xD5, 0x87, 0x96, 0x78, 0x22, 0xB6, 0x48, 0x6C, 0x45, 0xC7, 0x5A, 0x16, 0x80, 0xFD, 0xE4, 0x8C, 0xBF, 0x01, 0x1F, 0x4B, 0x79, 0x24, 0xA0, 0xB4, 0x23, 0x4D, 0x3B, 0xC5, 0x5D, 0x6F, 0x0D, 0xC9, 0xD4, 0xCA, 0x55, 0xE0, 0x39, 0xAD, 0x2B, 0xCD, 0x2C, 0xEC, 0xC2, 0x6B, 0x30, 0xE6, 0x0C, 0xA8, 0x9A, 0x2F, 0xF6, 0xE8, 0xBB, 0x32, 0x57, 0xFB, 0x0B, 0x9D, 0xF2, 0x3F, 0xB5, 0xF9, 0x59, 0xE5, 0x10, 0xCF, 0x51, 0x41, 0xE9, 0x50, 0xDF, 0x26, 0x74, 0x58, 0xCB, 0x64, 0x54, 0x73, 0xAB, 0xF4, 0xB2, 0x9F, 0x18, 0xF8, 0x4E, 0xFE, 0x08, 0x1D, 0x4F, 0x49, 0xD3, 0xAC, 0x38, 0x12, 0x77, 0x11, |
被打
看到一个提取ir的方法,根据Lu1u师傅的博客操作即可
Dual personality
简而言之就是在32位程序里执行64位代码。sub_401120用于做出这种转换。
自己patch程序的32位标志为64位标志即可用64位IDA打开反汇编。
结合两个程序的代码自己看流程即可,数据可以调试取得,注意反调试的地方。(好吧!我调不对,我硬看的x)
加密一共有3段,第一段是加,第二段是移位,第三段是异或,但是我明明改了反调试的地方,最后一段取的异或数据还是不对啊啊啊啊啊,不知道哪里有问题(可能是后面改了,但是断点断不到64位代码里所以有点问题)
只能patch输出用交互取加密后的密文,然后跟前两段加密后的结果异或,得到用于异或的数据。
1 |
|
EasyVT
每次都会因为很傻逼的问题卡半年。。。
根据main函数里的指令对比常量表即可,wp很多我就不抄一遍了……啊,我真是越来越懒了
1 |
|
关于本文
本文作者 云之君, 许可由 CC BY-NC 4.0.