13.c语言使用vs2022分析c语言程序并手写x86与x86_64内联汇编程序
[toc]
用C语言写一个x86内联汇编程序
1. 用C语言写一个程序,内容为调用MessageBoxA函数
完整代码:
1 | //Message.c |
结果如图所示:

2. 用C语言与x86内联汇编写一个程序,内容为调用MessageBoxA函数
完整代码
1 |
|
结果如图所示:

3. 用C语言与x86内联汇编写一个程序,内容为使用内联汇编调用C语言函数
完整代码
1 |
|
结果如图所示:

4.用C语言与x86内联汇编写一个程序,使用内联汇编调用C语言中的变量
完整代码:
1 |
|
结果如图所示:

5. 用C语言与x86内联汇编写一个程序,使用内联汇编调用C语言中的指针类型变量
完整代码:
1 |
|
结果如图所示:

6. 用C语言与x86内联汇编写一个程序,使用内联汇编调用MessageBoxA并传递参数
以下为完整代码:
1 |
|
结果如图所示:

7. 用C语言与x86内联汇编写一个程序,汇编指令与C语言代码分开引用
在项目中勾选Masm
新建一个文件命名为AsmMessage.asm
完整代码如下
Message.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14;AsmMessage.asm
.586
.model flat,stdcall,c
option casemap:none
.data
.code
AsmMessageBoxA_ proc
mov eax,[esp+4]; eax = 'paddr'
call eax
ret
AsmMessageBoxA_ endp
endMessage.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22//Message.c
extern int AsmMessageBoxA_(void* paddr);
void Message()
{
MessageBoxA(NULL, "HellWorld", "Text", MB_OK);
}
int main(int argc, char** argv)
{
printf("MessageBoxA address is 0x%p\n", &MessageBoxA);
printf("AsmMessageBoxA() address is 0x%p\n", &AsmMessageBoxA_);
AsmMessageBoxA_(&Message);
MSG msg;
while (GetMessageW(&msg, NULL, NULL, NULL))
{
}
return 0;
}运行结果如下:

8. 关于x86汇编的写法以及堆栈实验以下6个汇编程序堆栈完全平衡
1.[esp+4]为传过来的第一个参数,如果有二个参数,第二个参数应为[esp+8]
1 | ;AsmMessage.asm |
2. 使用push压入一个参数后需要将esp加4
1 | ;AsmMessage.asm |
3.pop一个寄存器等同于add esp,4
1 | ;AsmMessage.asm |
4.sub esp,4等同于push 一个寄存器
1 | ;AsmMessage.asm |
5.使用堆栈通过寄存器来赋值与取值
1 | ;AsmMessage.asm |
6.push与pop指令可以操作堆空间
1 | ;AsmMessage.asm |
9. c语言程序使用Naked函数内联x86汇编
完整代码
1 | //Messageb.c |
用C语言写一个x86_64内联汇编程序
1. 用C语言与x86内联汇编写一个程序,汇编指令与C语言代码分开引用
在项目中勾选Masm
新建一个文件命名为AsmMessage.asm
完整代码如下
Message.asm
1
2
3
4
5
6
7
8
9
10
11;Message.asm
.data
.code
AsmMessageBoxA_ proc
sub rsp,8h
call rcx ;rcx = 'paddr'
add rsp,8h
ret
AsmMessageBoxA_ endp
endMessage.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23//Message.c
extern int AsmMessageBoxA_(void* paddr);
void Message()
{
MessageBoxA(NULL, "HellWorld", "Text", MB_OK);
}
int main(int argc, char** argv)
{
printf("MessageBoxA address is 0x%p\n", &MessageBoxA);
printf("AsmMessageBoxA() address is 0x%p\n", &AsmMessageBoxA_);
AsmMessageBoxA_(&Message);
MSG msg;
while (GetMessageW(&msg, NULL, NULL, NULL))
{
}
return 0;
}运行成功
2.关于x64的堆栈平衡,以下3个程序堆栈完全平衡
1.使用push与pop指令平衡堆栈
1 | ;AsmMessage.asm |
2.使用sub rsp,8h与pop指令平衡堆栈
1 | ;AsmMessage.asm |
3. 使用全局变量保存数据并call两次
1 | ;AsmMessage.asm |
3.在x86_64位汇编中写一个汇编调用MessageBoxA的程序
Message.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//Message.c
int AsmMessageBoxA_(void* pAddr);
int main(int argc, char** argv)
{
printf("0x%p", &MessageBoxA);
MessageBoxA(NULL, "HellWorld", "Text", MB_OK);
AsmMessageBoxA_(&MessageBoxA);
MSG msg;
while (GetMessageW(&msg, NULL, NULL, NULL))
{
}
return 0;
}AsmMessage.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18; AsmMessage.asm
.data
text db 'Call MessageBoxA Success', 0
.code
AsmMessageBoxA_ proc
mov rbx, rcx; rcx = 'paddr'
sub rsp, 28h
mov r9, 2
mov r8, 0
lea rdx, text
mov rcx, 0
call rbx
add rsp, 28h
ret
AsmMessageBoxA_ endp
end
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
