本文首发于“合天智汇”民众号,未经允许,克制转发!
上次我们对主函数剖析完成了,逆向入门剖析实战(一)那么这次我们对子函数IsAlreadyRun举行剖析。
C语言代码
IsAlreadyRun函数的C语言代码如下图所示:
下面临其汇编代码举行剖析:
rep stosd之前,同样是入栈操作,我们无需仔细追究,重点关注call函数。
1. CreateMutexA函数
首先凭据call ds:CreateMutexA
这一条指令便可得知挪用了CreateMutex函数(注:CreateMutexA是在Ascii 环境下的,CreateMutexW是unicode环境下的)。
上次我们提到过,在函数挪用之前,若是有参数需要通报,需要使用push先将参数从后往前入栈。那么我们来看下call ds:CreateMutexA前面的三条push指令划分代表什么意思?若是查呢?这就用到异常常用的一个文档–msdn文档,这个文档是微软写的,先容了Windows API函数,基本上遇到的函数都可以在这里查到,好比CreateMutex这个函数对应的地址是:https://docs.microsoft.com/zh-cn/windows/win32/api/synchapi/nf-synchapi-createmutexa
从官网可以看到对应的函数注释,详细先容了这个函数的作用,参数,返回值等:
三个参数lpMutexAttributes,bInitialOwner,lpName中第三个参数lpName的意思是互斥工具的名称,另外两个在此处不睁开先容了,感兴趣的可以去查看msdn文档。现在我们再回过头来仔细看一下ida Pro给的反汇编代码:
是不是和MSDN上的三个参数反过来就对应上了?第一条push指令对应的是lpName这个参数,以是凭据ida pro右边给出的备注,可以得知这个互斥工具的名称是TEST。上一次也提到过,函数挪用完成后,VC中,会使用eax寄存器来保留函数的返回值。在这里也是一样的,call ds:CreateMutexA的返回值会存入eax寄存器。
2. 跳转剖析
我们继续剖析下面的汇编代码:
凭据call __chkesp可知是挪用了栈平衡错误检测函数,这里我们无需剖析。之后,
mov指令将挪用CreateMutexA函数的返回值eax先移动到ebp+var_4的地址上,之后又与0对比,若是两者相等,则跳转到 loc_40107D位置。即,若是CreateMutexA函数的返回值为0,则跳转 loc_40107D位置。
下面分两种情形举行讨论,一种是CreateMutexA函数的返回值为0,一种是不为0。
漫谈LiteOS-端云互通组件-MQTT开发指南(上)
2.1. CreateMutexA返回值为0
首先剖析CreateMutexA函数的返回值为0的情形:
跳转到这个位置之后,执行xor eax,eax这条指令,上次也提到过xor eax,eax直接会将eax的值设置为0,这是很常见的一种将eax置为0的方式。
执行完这条指令后,会到loc_40107F位置,凭据pop出栈指令、call __chkesp、retn等指令可知,这是子函数IsAlreadyRun挪用完要返回主函数。
那么,IsAlreadyRun函数的返回值是多少呢?返回值存在eax中,由前面可知,eax在CreateMutexA函数的返回值为0情形下,eax值为0(xor eax,eax的作用),以是IsAlreadyRun函数的返回值也是0,即IsAlreadyRun返回值为false。
对应的C语言代码:
即,当hMutex = ::CreateMutex(NULL, FALSE, “TEST”)执行后获得的hMutex为0时的场景,子函数IsAlreadyRun直接执行return FALSE;
2.2. CreateMutexA返回值不为0
之后,剖析CreateMutexA函数的返回值不为0的情形:
此时,由于eax不为0,以是不会跳转到loc_40107D这个位置,而是执行call ds:GetLastError执行挪用GetLastError函数。后面又执行call __chkesp 挪用栈平衡错误检查函数,我们在这里无需剖析。之后执行cmp eax,0B7h指令,由于GetLastError函数的返回值存储在eax中,此处其实是在看GetLastError返回值是否即是16进制的B7,对应10进制的183。
若是eax的值不即是183,那么跳转到loc_40107D,之后和上一种情形一样,将eax置为0,然后返回主函数。
若是eax的值即是183,则执行mov eax,1指令,然后跳转到loc_40107F位置,返回主函数。
那么这个183到底代表什么意义呢?通过查询MSDN文档,我们可以得知,它恰好对应常数ERROR_ALREADY_EXISTS。
对比我们写的C语言代码:
也就是GetLastError函数的返回值即是ERROR_ALREADY_EXISTS时,返回true;否则,返回false。
到此为止,整个代码剖析完毕。谢谢列位耐心的阅读,若有不当之处,迎接指出。
参考书籍:
《Windows黑客编程手艺详解》甘迪文著–北京:人民邮电出版社,2018年12月。
《C++反汇编与逆向剖析手艺揭秘》钱松林,赵海旭著–北京:机械工业出版社,2011年9月。
《恶意代码剖析实战》 (美)Michael Sikorski / Andrew Honig 著,诸葛建伟,姜辉,张光凯译 — 北京:电子工业出版社,2014年4月,原书名:Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software。
《汇编语言》王爽 著–2版,北京:清华大学出版社,2008年4月。
原创文章,作者:28x29新闻网,如若转载,请注明出处:https://www.28x29.com/archives/5832.html