【VS】VS2022 Windows X64 下C/C++与汇编(asm)混写并且调用lib学习笔记 - 指南
【VS】VS2022 Windows X64 下C/C++与汇编(asm)混写并且调用lib学习笔记
文章目录
一、 前言
之前学习了liunx下的shellcode,之后分析了Windows下msf的shellcode汇编实现,然后听了队内逆向大佬讲的x86内联汇编以及各种利用方法,于是思考能不能用x64写汇编,踩了很多坑,于是写此文记录学习过程。
前置天赋点:
- C/C++
- AMD64 汇编(下文简称asm)
- ctf二进制
参考:
https://bbs.huoban.com/thread-5667-1-1.html
https://www.cnblogs.com/AD-milk/p/13711369.html
二、环境搭建
2.1 Visual Studio 2022(下文简称vs2020和vs)
主要的工作负债如图
新建的时候选择控制台(其实选什么没什么关系,你愿意写gui马可以选gui)
跟着添加
直接输入fyn.asm,命名按照自己喜好即可
跟着选

选择
接下来设置(注意是在哪里右键)
三、写代码
3.1 main.cpp
在主要的文件中写:
#include <stdio.h>
extern "C" void __stdcall asm_func();
int main() {
asm_func();
return 0;
}
解释:
extern "C": 使用C函数形式调用外部函数__stdcall: 由外部函数控制扩展和清理栈
至于函数名按需要取
3.2 fun.asm
includelib ucrt.lib
includelib legacy_stdio_definitions.lib
.data
fmt db "Text from C:1111", 10, 0 ; "\n"
.code
align 16
;Function prototypes
printf PROTO arg1:PTR byte
asm_func proc
sub rsp, 28h; Shadow space (32字节) + 保证16字节对齐
mov r10, rcx
lea rcx, fmt; 第1个参数: format string
call printf
add rsp, 28h
ret
asm_func endp
end
这里讲究的比较多
3.2.1 includelib
includelib ucrt.libincludelib legacy_stdio_definitions.lib
这两条指令是导入lib供下文使用(例如printf),具体要用什么函数就要导入对应的lib,理论上导入ucrt.lib就可以了,但是微软在VS 2017后分离了一些经典的输入输出导出表到别的地方,但是微软为了兼容又在legacy_stdio_definitions.lib将它们再次导出了,所以可以用了。
注意 这里如果在main.cpp里include后仍然要导入一遍。
检查一个lib导出了什么的命令,请记得在VS2020控制台内打开
方法一:
方法二:
可以看到导出了什么东西
dumpbin /exports C:\Windows\System32\ucrtbase.dll
3.3 .data
.data
fmt db "Text from C:1111", 10, 0 ; "%s\n"
fmt理解为变量名字,可以随便取db是define byte的缩写,表示定义一个或多个字节(byte)常用于定义字符串、字符、字节数据等。每个字符会被翻译成一个字节(ASCII 编码)"Text from C:1111", 10, 0的意思是 Text from C:1111 + \n + \0 (ASCII 编码)
把用到的字符串和数据丢到这里即可,当然,在下文手动组装也可以
3.4 .code
.code
align 16
;Function prototypes
printf PROTO arg1:PTR byte
asm_func proc
sub rsp, 28h ; Shadow space (32字节) + 保证16字节对齐
mov r10, rcx
lea rcx, fmt ; 第1个参数: format string
call printf
add rsp, 28h
ret
asm_func endp
align 16需要16位对齐(pwn手看到这个已经PTSD了)printf PROTO arg1:PTR byte声明函数以及变量位置、类型、数量(方便编译器检查罢了,可以不加,但是推荐加)asm_func proc和asm_func endp前面是函数名,后面是标识开始和结束,这个函数名要和main.cpp里的一致(就是要一起改)
可以定义多个函数,在end前面可以定义多个xxxx endp和xxxx proc
3.5 end
提示结束
运行直接run即可
四、总结
这种方法的优点是不用从头写,本体既是加载器,方便嵌入其中,有很多妙妙操作也可以实现(比方说手动实现printf里面藏一点好东西之类的),缺点也很明显,过度依赖vs2022,迁移性很差。
浙公网安备 33010602011771号