首先打开文件unpackme#1.aC.exe,分析其中的节区信息,如下:
对节区头中包含节区的内存展示:
文件RAW地址 |
|
内存RVA地址 |
||
400 磁盘节区起始地址 |
|
1000 内存节区起始地址 |
||
..... ..... ..... 800 |
280 |
text |
..... ..... ..... 2000 |
400 |
..... A00 |
200 |
rdata |
..... 3000 |
138 |
...... C00 |
200 |
data |
...... 4000 |
2c |
...... 1400 |
800 |
pdata |
...... 4630 |
630 |
注意上面表格两边虽然格式上对齐,但是数值上是不一样的 |
从PE头可知,程序的EP是1000
加上imagebase的地址:
所以初始ep地址为: 1000 + 400000 = 401000
如下图:
下面开始对程序进行逐步分析:
开始就是一个跳转语句 call 004010e9
在4010e9这个地方对EAX压入了一个值 004010f5,然后调用40109b
在40109b这个地方,我们看到一个循环,对从内存地址004010f5开始的154个字节进行异或44h运算。即从内存4010f5 到内存401248。结束之后再调用4010bd.
这里有两个循环,
第一个是针对从内存401007开始的7Fh个字节进行异或07的运算,即从内存401007到内存401086。
第二个循环是又对内存地址004010f5开始的154个字节进行异或11h运算。
上述两个循环结束之后,又回到调用4010bd的地方,压入eax(4010f5)之后,调用了
401039.
401039这个地址是一个求和的循环,对从内存地址004010f5开始的154个双字进行了求和,
不计算溢出部分,将结果保存在EDX中。在比较结果会前调用了40108a,主要作用是解码绘图函数调用,如下图所示
对从内存40124a到内存401280的地址数据进行异或17运算,从而获取绘图函数
比较edx和一个设定的固定值31EB8DB0,不相等就是显示crc错误。相等就调用40121e
在40121e,我们看到如下图所示
调用窗口显示字符,处理函数DialogProc地址为4010f5.
查看4010f5的内容
在这里我们看到了两个显示字符串的位置
分别为:
Address Hex dump ASCII
0040110A 59 6F 75 20|6D 75 73 74|20 75 6E 70|61 63 6B 20| You must unpack
0040111A 6D 65 20 21|21 21 me !!!
这里共22个字节
对应文件的地址为:Raw = 40110a-401000+400 = 50a
相应的22个字节为:0C 3A 20 75 38 20 26 21 75 20 3B 25 34 36 3E 75 38 30 75 74 74 74
Address Hex dump ASCII
0040111A 59 6F 75|20 6D 75 73| You mus
0040112A 74 20 70 61|74 63 68 20|74 68 69 73|20 4E 41 47| t patch this NAG
0040113A 20 21 21 21| !!!
这里共27个字节raw=401123-401000+400 = 523
相应的27个字节为:0C 3A 20 75 38 20 26 21 75 25 34 21 36 3D 75 21 3D 3C 26 75 1B 14 12 75 74 74 74
从上面的分析,我们知道40110a 和401123 都在内存区间 4010f5 到401248 中间,
也就是说进行了两次异或操作,第一次是异或44,第二次是异或11,所以总的就是异或55.
为了验证我们的想法,我们把从文件找到的两个字符串进行了异或55操作,结果如下:
0C 3A 20 75 38 20 26 21 75 20 3B 25 34 36 3E 75 38 30 75 74 74 74
转变为:
59 6f 75 20 6d 75 73 74 20 75 6e 70 61 63 6b 20 6d 65 20 21 21 21
验证了我们的想法。于是我们也仿造了相应长度的字符,如下:
和
然后,我们对这两个字符串进行了异或55操作
得到
1b 3a 22 75 1c 75 20 3b 25 34 36 3e 75 3c 21 75 20 26 30 75 2d 74
和
22 30 75 22 34 3b 21 75 21 3a 75 20 26 30 75 36 3d 30 36 3e 26 20 38 74 74 74 74
将这两个字符串替换文件中原来的两个字符串,如下图所示:
和
替换了之后,再次执行,就会出现crc错误,因为求和的值变了,所以我们需要修改前文提到过的定值31EB8DB0,经过调试,我们发现,循环相加之后的结果edx为CD87294B
相应的文件地址为:raw=401062-401000+400 = 462
又因为401062的内存地址位于401007到401086之间,所以采用的是异或7的操作。
针对值CD87294B,我们进行异或7操作,得到4c 2e 80 ca
修改为:
前面两个字节是操作码,后面4个字节是我们本次修改的内容,然后我们开始执行新修改的文件unpackme#1.aC_sum.exe,结果如下:
完
附:
手上没有找到异或的工具,临时写的转化小函数
void change(int a[], int length, int xorvalue)
{
for(int i=0; i<length; i++)
{
int temp = xorvalue;
temp = temp ^ a[i];
printf("%x ",temp);
}
printf("\n");
}