吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2555|回复: 1
收起左侧

[其他转载] 【笔记】借助实例分析回顾汇编指令

[复制链接]
leo_zch 发表于 2017-11-16 15:20
本帖最后由 leo_zch 于 2017-11-16 15:27 编辑

这个分析是看恶意代码分析实战时,为了回顾一些汇编指令以及熟悉分析流程而写的,发在了自己的博客,加深一下理解。现在注册了论坛,搬过来让大家看看有啥毛病,欢迎指正
1、字符串

字符串

字符串

根据Internet、Connection、OpenUrl等可以看出程序有url访问操作,访问的url可能就是http://www.practicalmalwareanalysis.com/cc.htm,还有一个Parsed command,可能涉及对参数的解析
2、打开汇编窗口,程序从_main开始,这里简单分析一下_main函数:

首先,_main调用了sub_401000(),接下来拷贝了EAX中的值并与0进行比较,由此可以还原一个函数调用:var_4 = sub_401000()
然后,cmp和jnz指令发生条件跳转,cmp比较var_4和0,如果var_4==0,ZF置1,否则置0,从而决定jnz是否发生跳转。jnz当ZF为0时发生跳转,此时var_4!=0,写出伪代码如下:
[C] 纯文本查看 复制代码
if(var_4==0){
//不发生跳转
xor eax,eax
jmp short loc_40117B
}else{
jmp loc_401148
}

3、sub_401000()

_main首先调用了sub_401000(),并返回一个Int值

在sub_401000()主程序中,InternetGetConnectedState函数被调用,由其名字不难猜出这是一个判断网络连接状态的函数,msdn上有其介绍如下:
BOOL InternetGetConnectedState(
_Out_ LPDWORD lpdwFlags,
_In_ DWORD dwReserved
);

两个参数:
lpdwFlags is a Pointer to a variable that receives the connection description,函数通过这个参数判断特定网络是否正常连接,例如LAN、MODEM等,但是没有0,猜测应该是只要有一个可以连接就返回TRUE。
dwReserved为保留字,必须为0
这里逻辑如下:如果存在网络连接,InternetGetConnectedState返回True,cmp将返回值与0比较使ZF置0,从而jz不会跳转。伪代码:
[C] 纯文本查看 复制代码
if(InternetGetConnectedState(0,0)){...}
else jmp loc_40102B

接下来无论跳转不跳转,sub_40117F(const char *format_str)都会被调用,参数为一个格式化字符串,根据前面的函数状态和这里字符串内容可以推知:sub_40117F()为printf函数
这两个分支打印了字符串后,进行了类似的操作:操作EAX,跳到loc_40103A退出函数.
第一个有网络连接时,EAX被置1,无连接跳转后通过xor eax,eax;EAX被置0
由调用约定,EAX一般存储被调函数的返回值
由此,完整伪代码如下:
[C] 纯文本查看 复制代码
if(InternetGetConnectedState(0,0)){
printf("Success,Internet connection\n");
return 1;
}else{
printf("Error,no connected\n");
return 0;
}

4:伪代码扩充


[C] 纯文本查看 复制代码
int _main(){
int flag = sub_401000();
if(flag){
//jmp loc_401148;
var_8 = sub_401040();
//test eax,eax;相当于&操作,
if(var_8&var_8) reutrn 0;
//jmp loc_40115C;之前已经分析过sub_40117F为printf,可以在IDA中对sub_40117F进行重命名
printf("Success: Parsed command is %c\n",ecx_command);
Sleep(EA60h);
}
return 0;
}

5、sub_401040()


在图中框出了几个函数调用和跳转,总结分析可知,该函数访问了szUrl,如果访问成功跳到loc_40109D,否则打印失败信息,关闭网络句柄。
1)InternetOpen:Returns a valid handle that the application passes to subsequent WinINet functions. If InternetOpen fails, it returns NULL. To retrieve a specific error message, call GetLastError.
即如果打开成功,它会返回一个有效的句柄。interHandler = InternetOpen(szAgent,0,0,0,0)
2)InternetOpenUrl:Returns a valid handle to the URL if the connection is successfully established, or NULL if the connection fails. To retrieve a specific error message, call GetLastError. To determine why access to the service was denied, callInternetGetLastResponseInfo.
通过1)获得的句柄请求url,获得一个URL的句柄。urlHandler=InternetOpenUrl(interHandler,szUrl,0,0,0,0)
3)cmp [ebp+hFile],0;urlHandler与0比较,如果不为NULL,jmp loc_40109D
伪代码如下:
[C] 纯文本查看 复制代码
int sub_401040(){
interHandler = InternetOpen(szAgent,0,0,0,0);
urlHandler=InternetOpenUrl(interHandler,szUrl,0,0,0,0);
if(urlHandler){
jmp loc_40109D;
}
printf(aError2_1FailTo);
urlHandler.close();
return 0;
}

6、loc_40109D


当urlHandler不为NULL时,首先调用了
1)var_4 = InternetReadFile(hFile,*lpBuffer,256,*lpdwNumberOfBytesRead)
注: hFile [in]:Handle returned from a previous call to InternetOpenUrl.
lpBuffer [out]:Pointer to a buffer that receives the data.
dwNumberOfBytesToRead [in]:Number of bytes to be read.
lpdwNumberOfBytesRead [out]:Pointer to a variable that receives the number of bytes read. InternetReadFile sets this value to zero before doing any work or error checking.
即从hFile中读取512字节的数据存到lpBuffer中,成功返回True,否则返回False
2)接下来判断是否读取成功,成功则跳转到loc_4010E5继续执行,否则打印错误信息,关闭句柄,退出
[C] 纯文本查看 复制代码
if(var_4) jmp loc_4010E5;
else{
printf(aError2_2FailTo);
interHandler.close();
return 0;
}

3)loc_4010E5:在这里,程序将buffer与'<‘比较,var_20F与‘!’比较。。。但是Buffer我们已经知道Buffer是一个连续的512字节的数组,所以这里应该是将Buffer[0-4]的前四字节与'<!–‘比较,如果前面比较成功,则将第五字节存入al,然后返回退出。


我们需要修改此处的栈,将Buffer定义为一个512字节的数组,在loc_4010E5处按Ctrl-K,然后右键Buffer第一个字节,将Buffer定义为一个512字节的数组

128-191x300.png




7、如此,sub_401040()的完整伪代码就可以写出来了,如下
[C] 纯文本查看 复制代码
int sub_401040(){
interHandler = InternetOpen(szAgent,0,0,0,0);
urlHandler=InternetOpenUrl(interHandler,szUrl,0,0,0,0);
if(urlHandler){
//jmp loc_40109D;
var_4 = InternetReadFile(hFile,*lpBuffer,256,*lpdwNumberOfBytesRead);
if(var_4) {
//jmp loc_4010E5;
if(buffer[0]=='<'){
if(buffer[1]=='!'){
if(buffer[2]=='-'){
if(buffer[3]=='-') return buffer[4];
}
}
}
}
}
printf(aError2_1FailTo);
urlHandler.close();
return 0;
}

8、回顾_main函数主体,首先判断电脑是否有网络连接,然后访问http://www.practicalmalware.com/cc.htm并解析命令,var_8用来存储命令字符,然后判断var_8是不是空,如果不是,打印解析成功的命令,然后Sleep()
[C] 纯文本查看 复制代码
int _main(){
int flag = sub_401000();
if(flag){
//jmp loc_401148;
var_8 = sub_401040();
//test eax,eax;相当于&操作,
if(var_8&var_8) reutrn 0;
//jmp loc_40115C;之前已经分析过sub_40117F为printf,可以在IDA中对sub_40117F进行重命名
printf("Success: Parsed command is %c\n",ecx_command);
Sleep(EA60h);
}
return 0;
}

9、当然这些可以通过IDA的F5直接看出,在这里主要是为了巩固一些知识,并且逆向中一般并不会很容易的就能F5出正确的结果。

_main

_main

3

3

4

4

5

5

6

6
127-300x135.png
129-2-300x125.png

免费评分

参与人数 1热心值 +1 收起 理由
lin_xop + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ProgramerFangL 发表于 2017-11-16 16:12
大佬大佬,先给大佬留个好印象,顺便留个脚印以后看
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 08:28

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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