[英]IDA disassembly produces completely different code to ASM file for exe compiled in Visual Studio 2017
I compiled a simple program using Visual Studio 2017 我使用Visual Studio 2017编译了一个简单程序
#include <stdio.h>
int main()
{
printf("hello, world\n");
return 0;
}
I compile it with command line 我用命令行编译
cl 1.cpp /Fa1.asm
This gives me assembly code that (mostly) makes sense to me 这给了我大多数情况下有意义的汇编代码
; Listing generated by Microsoft (R) Optimizing Compiler Version 19.14.26429.4
INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES
CONST SEGMENT
$SG5542 DB 'hello, world', 0aH, 00H
CONST ENDS
PUBLIC ___local_stdio_printf_options
PUBLIC __vfprintf_l
PUBLIC _printf
PUBLIC _main
PUBLIC ?_OptionsStorage@?1??__local_stdio_printf_options@@9@4_KA ; `__local_stdio_printf_options'::`2'::_OptionsStorage
EXTRN ___acrt_iob_func:PROC
EXTRN ___stdio_common_vfprintf:PROC
; COMDAT ?_OptionsStorage@?1??__local_stdio_printf_options@@9@4_KA
_BSS SEGMENT
?_OptionsStorage@?1??__local_stdio_printf_options@@9@4_KA DQ 01H DUP (?) ; `__local_stdio_printf_options'::`2'::_OptionsStorage
_BSS ENDS
; Function compile flags: /Odtp
_TEXT SEGMENT
_main PROC
; File c:\users\mr dai\documents\michael\study\cybersecurity\reverseengineering4beg\random\random\random.cpp
; Line 3
push ebp
mov ebp, esp
; Line 4
push OFFSET $SG5542
call _printf
add esp, 4
; Line 5
xor eax, eax
; Line 6
pop ebp
ret 0
_main ENDP
_TEXT ENDS
; Function compile flags: /Odtp
; COMDAT _printf
_TEXT SEGMENT
__Result$ = -8 ; size = 4
__ArgList$ = -4 ; size = 4
__Format$ = 8 ; size = 4
_printf PROC ; COMDAT
; File c:\program files (x86)\windows kits\10\include\10.0.17134.0\ucrt\stdio.h
; Line 954
push ebp
mov ebp, esp
sub esp, 8
; Line 957
lea eax, DWORD PTR __Format$[ebp+4]
mov DWORD PTR __ArgList$[ebp], eax
; Line 958
mov ecx, DWORD PTR __ArgList$[ebp]
push ecx
push 0
mov edx, DWORD PTR __Format$[ebp]
push edx
push 1
call ___acrt_iob_func
add esp, 4
push eax
call __vfprintf_l
add esp, 16 ; 00000010H
mov DWORD PTR __Result$[ebp], eax
; Line 959
mov DWORD PTR __ArgList$[ebp], 0
; Line 960
mov eax, DWORD PTR __Result$[ebp]
; Line 961
mov esp, ebp
pop ebp
ret 0
_printf ENDP
_TEXT ENDS
; Function compile flags: /Odtp
; COMDAT __vfprintf_l
_TEXT SEGMENT
__Stream$ = 8 ; size = 4
__Format$ = 12 ; size = 4
__Locale$ = 16 ; size = 4
__ArgList$ = 20 ; size = 4
__vfprintf_l PROC ; COMDAT
; File c:\program files (x86)\windows kits\10\include\10.0.17134.0\ucrt\stdio.h
; Line 642
push ebp
mov ebp, esp
; Line 643
mov eax, DWORD PTR __ArgList$[ebp]
push eax
mov ecx, DWORD PTR __Locale$[ebp]
push ecx
mov edx, DWORD PTR __Format$[ebp]
push edx
mov eax, DWORD PTR __Stream$[ebp]
push eax
call ___local_stdio_printf_options
mov ecx, DWORD PTR [eax+4]
push ecx
mov edx, DWORD PTR [eax]
push edx
call ___stdio_common_vfprintf
add esp, 24 ; 00000018H
; Line 644
pop ebp
ret 0
__vfprintf_l ENDP
_TEXT ENDS
; Function compile flags: /Odtp
; COMDAT ___local_stdio_printf_options
_TEXT SEGMENT
___local_stdio_printf_options PROC ; COMDAT
; File c:\program files (x86)\windows kits\10\include\10.0.17134.0\ucrt\corecrt_stdio_config.h
; Line 85
push ebp
mov ebp, esp
; Line 87
mov eax, OFFSET ?_OptionsStorage@?1??__local_stdio_printf_options@@9@4_KA ; `__local_stdio_printf_options'::`2'::_OptionsStorage
; Line 88
pop ebp
ret 0
___local_stdio_printf_options ENDP
_TEXT ENDS
END
However I open the exe with IDA and the disassemble spits out something completely unintelligible. 但是,我用IDA打开了exe,反汇编却吐出了一些完全无法理解的东西。
Why is this the case? 为什么会这样呢? Does visual studio automatically obfuscate assembly code by default?
默认情况下,Visual Studio是否会自动混淆汇编代码? I googled but this doesn't seem to be the case.
我用谷歌搜索,但事实并非如此。 If so, how do I turn obfuscation off?
如果是这样,如何关闭混淆功能?
Thanks 谢谢
main
is not the entry point of you program, at this level. 在这个级别上,
main
不是您程序的入口点。
The C language is an abstraction, before main
can ran the runtime must be initialised . C语言是一种抽象,在
main
可以运行之前, 必须初始化运行时 。
C++ is even more complicated but the idea is the same: there is some code that is run before main
(otherwise who would initialise cout
for example?) C ++甚至更复杂,但是思想是相同的:在
main
之前运行一些代码(否则谁会初始化cout
?)
At the end of the day, all languages compile down to a binary PE, it's important to get familiar with that. 归根结底,所有语言都可以编译为二进制PE,熟悉这一点很重要。
I've compiled your program in order to show how to find main
. 我已经编译了您的程序,以展示如何查找
main
。
Note however that, based on your code, I assumed you were compiling a C file while looking at the disassembly it seems you compiled a C++ file. 但是请注意,根据您的代码,我假设您在查看反汇编时正在编译C文件,似乎您已编译了C ++文件。 C++ is notoriously more complex to reverse engineer.
众所周知,C ++对于逆向工程更为复杂。
The example below will differ from yours, mine is an x86 debug build. 下面的示例与您的示例不同,我的是x86调试版本。
First of all, IDA tells you where the PE entry point is in the Exports tab 首先,IDA会告诉您PE入口点在“ 导出”选项卡中的位置
If you double click it and follow the path the jmp
and call
instructions (there is only one path, you can't get lost) you arrive at a routine with two calls 如果双击它并遵循
jmp
和call
说明的路径(只有一条路径,就不会迷路),您将通过两次调用到达例程
VS generate a security cookie as the first thing and that's what the first function called does: VS首先生成一个安全cookie,这就是第一个调用的功能:
Note that this routine is pretty recognisable even without the IDA hints because it make very spot-on API calls, you can Google some of the function names in the picture to find the documentation. 请注意,即使没有IDA提示,该例程也非常容易识别,因为它可以进行非常即时的API调用,您可以在图片中使用Google的某些函数名称来查找文档。
Assessed that this is the security cookie generation routine we then get back to the previous one and enter the second call 评估这是安全性Cookie生成例程,然后我们返回上一个例程并输入第二个调用
This is the body of your program, not main
but where the CRT is initialised and finalised, including calling main
. 这是程序的主体,不是
main
而是CRT初始化和完成的地方,包括调用main
。
Take a look at the flow-chart in the lower left corner and see that most of the work is in the left branch (meaning that the right branch is an error condition). 查看左下角的流程图,看看大部分工作在左分支中(这意味着右分支是错误情况)。
main
is usually called a few call
s before _exit
or _cexit
. main
通常在_exit
或_cexit
之前称为几次call
。 We then move close to these calls: 然后,我们靠近这些调用:
If you hover over a function call IDA will show the function code. 如果将鼠标悬停在函数调用上,IDA将显示该函数代码。
Functions that are a single jmp
are present in the the debug build to help the debugger and are more often than not runtime functions. 调试构建中提供了单个
jmp
功能来帮助调试器,并且通常不是运行时功能。
The first circled function, when hovered, show a call to an "enviroment" routine, this is good since main
needs the program arguments (Windows don't pass the argument to the program, there is a specific API to get them). 当第一个带圆圈的函数悬停时,显示对“环境”例程的调用,这很好,因为
main
需要程序参数(Windows不会将参数传递给程序,有一个特定的API可以获取它们)。
This looks like a call to main
, the arguments match. 这看起来像是对
main
的调用,参数匹配。
In fact, if we enter the call we get to main
: 实际上,如果我们输入呼叫,则会到达
main
:
Of course, you could have found main
by simply looking for the "Hello, world!" 当然,您可以通过简单地查找“ Hello,world!”来找到
main
。 string in the "String view" ( Shift + F12 ) but in a real world scenario of reverse engineering this almost always not possible. 在“字符串视图”( Shift + F12 )中输入字符串,但是在现实世界中,进行逆向工程几乎总是不可能的。
Making program and then reverse engineering them is a very good approach, if you have VS installed, you may have the MS DIA SDK that allows IDA to read the pdb
files. 制作程序然后进行反向工程是一个很好的方法,如果您安装了VS,则可能拥有MS DIA SDK,该软件允许IDA读取
pdb
文件。
This greatly help with the reverse engineering, you can load two IDAs, one with the PDB and one without and compare. 这对逆向工程有很大帮助,您可以加载两个IDA,一个加载PDB,另一个不加载并进行比较。
Unfortunately, getting the MS DIA SDK may not be so easy. 不幸的是,获得MS DIA SDK可能并不容易。
Also, IDA FLIRT is a must. 另外,IDA FLIRT是必须的。
It's a library of method signature, it allows IDA to recognise the runtime functions, making it very easy to focus on the application real code. 这是一个方法签名库,它使IDA能够识别运行时函数,从而使将重点放在应用程序实际代码上变得非常容易。 It's hard to find (and harder to generate) the signature though but they are totally worth it.
虽然很难找到(也很难生成)签名,但是它们完全值得。
Finally, note that debug build may be harder to reverse engineer due to the type of code generated. 最后,请注意,由于生成的代码类型不同,调试版本可能更难以逆向工程。
If you make a release build and reverse engineer it, you'll see it's easier to get to main
. 如果您进行发布构建并对它进行反向工程,您会发现进入
main
更容易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.