‘壹’ 将汇编代码转换为c语言
目前的反编译软件,只存在将机器指令码反汇编成汇编代码,不存在将汇编代码反编译成C语言的,因为汇编代码是低级语言,最接近于机器码(具体可查看不同硬件平台的技术资料),每条汇编指令都对应一个固定的机器码,这样进行反汇编是可行的,而C语言属于高级语言,编译器没有能力将汇编语言翻译成C或更高级的语言。
‘贰’ 请问如何把汇编语言转成C语言
反过来是可以的,叫反汇编,但汇编无法转C,因为汇编是机器语言,C最终还是转化成汇编,想转的话只能人为的编一个C出来
‘叁’ 怎样能将汇编语言转换成c语言
1、打开IAR FOR STM8工程。
‘肆’ 有什么软件能把汇编语言转为C语言
把c语言程序编译链接成可执行文件,然后反汇编那个可执行文件,之后你看到的将是c语言程序的等价汇编语言程序.
‘伍’ 有没有将c语言源代码转换成汇编语言的软件
如果只是想得到C语言或C++语言的汇编代码
可以通过指定编译器的选项来达成目的,这里我们用1998年生产的Windows平台VC6.0的SDK举例(以传统的命令行编译环境方式,对应的IDE集成开发环境可在工程》设置里在编译选项里加入/Fa即可):
开始》运行,输入cmd启动命令行,
若安装了VC6.0的SDK(或其IDE集成开发环境),默认路径为"C:\Program Files\Microsoft Visual Studio“
命令行输入"C:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"回车执行初始化编译环境
命令行输入 mkdir CtoASMTest建立测试目录,并进入该目录,命令行输入 cd CtoASMTest
用记事本建立测试代码,命令行输入notepad CtoASM_test.c回车确认,输入以下测试C代码
int main(int argc,char* argv[]){
int i;
for(i = 0; i < argc; ++i){
printf("argv[%d] is:\t%s\n",i,argv[i]);
}
printf("CtoASM_test end.\n");
}
若直接默认编译,命令行输入cl CtoASM_test.c,则会产生对象文件*.obj和目标文件*.exe
命令行输入dir 列出测试目录文件清单如下,多了obj和exe编译产生的文件
CtoASM_test.c
CtoASM_test.exe
CtoASM_test.obj
若想得到c文件对应的汇编语言文件,可以指定汇编文件产生选项 /Fa,即cl /Fa CtoASM_test.c则会同时产生汇编文件CtoASM_test.asm,内容如下
TITLE CtoASM_test.c
.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif
PUBLIC _main
EXTRN _printf:NEAR
_DATA SEGMENT
$SG41 DB 'argv[%d] is:', 09H, '%s', 0aH, 00H
ORG $+3
$SG42 DB 'CtoASM_test end.', 0aH, 00H
_DATA ENDS
_TEXT SEGMENT
_argc$ = 8
_argv$ = 12
_i$ = -4
_main PROC NEAR
; File CtoASM_test.c
; Line 1
push ebp
mov ebp, esp
push ecx
; Line 3
mov DWORD PTR _i$[ebp], 0
jmp SHORT $L37
$L38:
mov eax, DWORD PTR _i$[ebp]
add eax, 1
mov DWORD PTR _i$[ebp], eax
$L37:
mov ecx, DWORD PTR _i$[ebp]
cmp ecx, DWORD PTR _argc$[ebp]
jge SHORT $L39
; Line 4
mov edx, DWORD PTR _i$[ebp]
mov eax, DWORD PTR _argv$[ebp]
mov ecx, DWORD PTR [eax+edx*4]
push ecx
mov edx, DWORD PTR _i$[ebp]
push edx
push OFFSET FLAT:$SG41
call _printf
add esp, 12 ; 0000000cH
; Line 5
jmp SHORT $L38
$L39:
; Line 6
push OFFSET FLAT:$SG42
call _printf
add esp, 4
; Line 7
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
其中还可以产生其它文件,可以参考编译器的选项说明,命令行输入cl /?查看帮助,其中关于产生的输出文件类型可以有以下选择
-OUTPUT FILES-
/Fa[file] name assembly listing file /Fo<file> name object file
/FA[sc] configure assembly listing /Fp<file> name precompiled header file
/Fd[file] name .PDB file /Fr[file] name source browser file
/Fe<file> name executable file /FR[file] name extended .SBR file
----------------------------------------------
补充,
其它平台的编译器也有类似的汇编输出选项,如类Unix平台的GNU编译器cc -S CtoASM_test.c和gcc -S CtoASM_test.c 都可以通过指定-S选项产生c或c++代码对应的汇编语言文件。
‘陆’ 如何将这段汇编语言转换成C语言
如何将这段汇编语言转换成C语言?题目分别提供了同一C语言代码的32位和64位汇编版本:很容易可以得出其源C语言代码:
int f(int** p){
return (**p=**p+4,*(int*)**p);
}
则函数体的返回值类型是int,参数p的类型是int**,其唯一的语句是return (**p=**p+4,*(int*)**p);
先把结论放在这,节约不想思考的同学的时间,不同编译器可能会有所不同,lea 0x4(%eax),%ecx指令可能会被编译器拆开成两段:mov (%eax),%ecx 和add 0x4,%ecx(对于64位,则是编译器把lea lea 0x4(%rax),%rcx,拆开成mov (%rax),%rcx 和add 0x4,%rcx,但是效果是一样的。
根据题目中函数体只有1句代码的信息,我们至少确定了这个代码是一个return语句,如此短小的函数当然只需要用到段内跳转和段内指针,不需要段地址信息,所以指针大小(64位的RIP和32位的EIP)只是偏移量大小,分别为64位(8字节)和32位(4字节)。
题目的设问有相当好的引导性,对比查看左边和右边的倒数第3个指令,我们可以看出:函数的返回值都是放在eax变量之中,说明返回值的类型大小是4个字节。而同时,我们知道在C语言中,64位和32位环境下,int类型的大小都是4个字节,所以第1空的答案不能是只有1字节的char类型,也不能是在32位环境下大小为4字节而在64位环境下大小为8字节的指针类型如char*、int*。综上,第1空的答案:函数f的返回值类型只能是int。
第2空则是考查C语言函数的参数传递,栈式参数传递,在call函数f把ip压入(分别为64位的RIP和32位的EIP)之前,先压入的是函数的实际参数,其类型暂时不知道,那就得从汇编指令中找出这个信息点:
C语言函数体标志就是:push %ebp→mov %esp,%ebp→函数体内部→pop %ebp→ret(对64位则是:push %rbp→mov %rsp,%rbp→函数体内部→pop %rbp→retq)
两边都是同一个简单的c语句得到的汇编语句(64位和32位),左边64位的第2、3、4行对应于右边的第2、3行(64位多用了一个rdi寄存器传递参数,可能是编译器选项不同的缘故,又因为main函数中调用函数f的指令没有给出,且不一定相同,故不影响判断)。
两边剩下的几行代码(左边2、3、4、5、6、7、8行,右边2、3、4、5、6、7行)的工作大同小异,从数据流上看(函数体内,对于32位0x8(%ebp)是第一个也是唯一一个参数,对于64位-0x8(%rbp)才是):
*p→eax,*eax→eax,eax+4→ecx(①),*p→edx,ecx→*edx,*eax→eax
可以简化为:
**p→eax,eax+4→ecx,ecx→**p,***p→eax
再简化为
**p+4→**p,***p→eax
注:(①)lea 0x4(%eax), %ecx 意思是取有效地址Load Effect Address,相比于mov 0x4(%eax), %ecx使用地址所指向的值*(eax+4)→ecx,lea指令只使用地址的值eax+4→ecx,少做一步。64位也是如此a。
(对于64位则是:
*p→rax,*rax→rax,rax+4→rcx,*p→rdx,rcx→*rdx,*rax→eax
可以简化为:
**p→rax,rax+4→rcx,rcx→**p,***p→eax
再简化为
**p+4→**p,***p→eax
)
看到数据流了,C语言语句自然也就呼之欲出了,即return (**p=**p+4,*(int*)**p)。(逗号,运算符的意思是从左到右计算式子,然后返回最后一个)
注意这里的+4指的是4个字节,而在64位32位中都一样,于是初步断定**p是固定大小类型变量,同时返回值是int类型的,故认为它(**p)是int,所以参数p的类型就是int**。
‘柒’ 怎么把汇编转换成C语言
如果 只是简单的几行,可以把编译后的exe文件,用系统自带的debug(windows键+R打开 运行窗口 输入debug 空格 exe的路径)打开debug后,输入U可以看到几行汇编代码。
如果是源代码 在vs编译器中调试运行,菜单上的:调试--窗口--反汇编 可以查看,如果是其他编译器 仔细找找也带反汇编的
要资料的话 [天书夜读-从汇编语言到Windows内核编程].谭文.邵坚磊. 这本书的基础部分里 有c语言与汇编的转换
‘捌’ 汇编语言可以直接转化为C语言吗有没有工具
汇编转化成C语言是非常困难的 因为有些指令只在汇编里面有C语言是不支持的
例如对寄存器操作之类的
目前还没有汇编转C语言的工具
大多数只能手动转但是转过的C语言再生成机器码没有原来汇编的效率高
‘玖’ 可以显示C语言编译成汇编语言全过程的编译器
如果你有用IDE的话,比如Visual Studio、Delphi等,应该都是可以设置C和汇编同时查看的。
一句C对应一句汇编,也相当于“单步编译”吧!