玩好.NET高级调试,你也要会写点汇编

net,高级,调试,写点,汇编 · 浏览次数 : 3607

小编点评

**背景1. 简介** 汇编是一种高级编程范式,需要对汇编指令有深入了解才能编写和运行。虽然使用汇编可以提升开发效率,但对于新手来说,学习汇编可能比较困难。 **搭建 x86 汇编环境** 1. 下载并安装 nasm。 2. 设置环境变量 PATH 以包含 nasm 的 bin、include 和 lib 文件。 3. 使用 VSCode 安装 The Netwide Assembler (NASM) 语法高亮插件和 GDB Debuggdb 插件。 4. 创建一个名为 `app.asm` 的汇编文件,并将其编译为可执行程序 `app.exe`。 **代码示例** ```assembly section .data msg db 'Hello World!', 0Ah , 0h; num1 dd 100; num1_int_fmt db 'num1=%d', 0Ah, 0h; num2 dq 3.14; num2_flt_fmt db 'num2=%lf', 0Ah, 0h; section .textglobal _main _main: push ebp ; 保存栈指针 mov ebp , esp ; 设置栈指针 printf("Hello World\\"); mov eax , msg ; 将 msg 的地址存入eax push eax ; 将 eax 的地址压入堆栈 call _printf ; 调用 printf 函数 add esp , 4 ; 增加堆栈空间 printf("num1=%d\",num1) mov eax , [num1] ; 从堆栈中读取 num1 的值 mov ebx , num1_int_fmt ; 将 num1 的值加载到 ebx push ebx ; 将 ebx 的地址压入堆栈 call _printf ; 调用 printf 函数 add esp , 0xc ; 增加堆栈空间 mov esp , ebp ; 设置栈指针 pop ebp ; 从栈中取出栈指针 ret ; 返回 ``` **总结** 学习汇编需要一些时间和精力,但对于对汇编原理感兴趣的用户来说,它是一种很有意义的学习目标。通过搭建汇编环境和编写一些简单的汇编程序,我们可以获得对汇编指令的深入了解。

正文

一:背景

1. 简介

.NET 高级调试要想玩的好,看懂汇编是基本功,但看懂汇编和能写点汇编又完全是两回事,所以有时候看的多,总手痒痒想写一点,在 Windows 平台上搭建汇编环境不是那么容易,大多还是用微软的 MASM + DosBox 搭一个 8086 的环境,这玩意距今快 50 年了。

在以前想快捷的写一点汇编,借助的是 VC 编译器的 __asm 在 C/C++ 代码中内嵌一点,比如下面这样。


int main()
{
	int num = 10;

	__asm {
		mov[num], 20
	}

	printf("num=%d", num);
}

便捷是便捷,但只能玩个局部,还是不够爽,所以本篇我们借助 nasm 来搭建一个 32bit 的汇编环境,当然 64bit 也是可以的, nasm 在 Linux 社区中非常有名。

二:搭建 x86 汇编环境

1. 前置基础构件

  1. nasm 下载

nasm 是一个非常有名的汇编器,官方网址:https://nasm.us/ 目前稳定版是 2.15.05

  1. gcc

大家都知道,源代码要变成可执行程序,步骤一般是: asm -> obj -> exe,前半部分由 nasm 负责,后半部分由 gcc 负责, gcc 是 Linux 上的刚需产品,在 Windows 上可以用 MinGW

下载网址:https://sourceforge.net/projects/mingw/files/MinGW

下载完之后,将下图中的 五项 全部勾选上进行安装。

bin, include,lib 全部配到环境变量的 PATH 中,然后打开控制台键入 gcc -v 看一下有没有配好。


PS C:\Users\Administrator\Desktop> gcc -v
Using built-in specs.
COLLECT_GCC=C:\MinGW\bin\gcc.exe
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/6.3.0/lto-wrapper.exe
Target: mingw32
Configured with: ../src/gcc-6.3.0/configure --build=x86_64-pc-linux-gnu --host=mingw32 --target=mingw32 --with-gmp=/mingw --with-mpfr --with-mpc=/mingw --with-isl=/mingw --prefix=/mingw --disable-win32-registry --with-arch=i586 --with-tune=generic --enable-languages=c,c++,objc,obj-c++,fortran,ada --with-pkgversion='MinGW.org GCC-6.3.0-1' --enable-static --enable-shared --enable-threads --with-dwarf2 --disable-sjlj-exceptions --enable-version-specific-runtime-libs --with-libiconv-prefix=/mingw --with-libintl-prefix=/mingw --enable-libstdcxx-debug --enable-libgomp --disable-libvtv --enable-nls
Thread model: win32
gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)
PS C:\Users\Administrator\Desktop>

  1. vscode 插件

这里我准备用 vscode 来写汇编代码,主要安装两个插件。

  • The Netwide Assembler (NASM)

这个 nasm 官方提供的 语法高亮 插件。

  • GDB Debug

gdb 已经内嵌到了 gcc 中,方便于 code 调试。

2. vscode 自动化构建

玩过 vscode 的朋友应该知道,自动化构建需要自己写 tasks.json,这里我简单写了一个。


{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "win86",
            "type": "shell",
            "command": "nasm.exe -f win32 -g -F cv8 -l app.lst app.asm; gcc app.obj -o app.exe",
            "problemMatcher": {
                "pattern": {
                    "regexp": "error"
                }
            },
            "group": "build",
            "presentation": {
                "focus": true,
                "panel": "dedicated",
                "reveal": "silent",
                "clear": true
            }
        }
    ]
}

然后就是配置启动 launch.json,代码如下:


{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "gdb",
            "request": "launch",
            "name": "GDB32",
            "program": "${workspaceFolder}/app.exe",
            "stopOnEntry": true,
            "preLaunchTask": "win86"
        },
        {
            "type": "gdb",
            "request": "launch",
            "name": "GDB64",
            "program": "${workspaceFolder}/app.exe",
            "stopOnEntry": true,
            "preLaunchTask": "win64"
        }
    ]
}

到这里基础设施就全部搭建完成了,然后就是写一个简单的汇编程序,实现三个 printf 的打印,代码如下:


extern _printf
SECTION .data

    msg             db      'Hello World!', 0Ah , 0h;
    
    num1            dd       100;
    num1_int_fmt    db      'num1=%d', 0Ah, 0h;

    num2            dq       3.14;
    num2_flt_fmt    db       'num2=%lf', 0Ah, 0h;

SECTION .text

global _main
 
_main:

    push ebp
    mov  ebp , esp 

    ; printf("Hello World\n");
    mov  eax , msg
    push eax 
    call _printf
    add  esp, 4

    ; printf("num1=%d",num1)
    mov  eax , [num1]
    push eax 
    mov  ebx , num1_int_fmt
    push ebx , 
    call _printf
    add  esp , 4

    ; printf("num2=%lf",num2)
    movq    xmm0  , [num2]
    sub     esp   , 0x8
    movsd   [esp] , xmm0
    mov     ebx   , num2_flt_fmt
    push    ebx 
    call    _printf
    add     esp   , 0xc

    mov esp , ebp
    pop ebp 

    ret

输出结果如下:

从上面的代码看,我需要自己协调栈平衡,自己去管理寄存器和内存的使用,真的是太爽了。

二:总结

汇编看多了,总想自己动手试试,如果你也有这种想法,可以搭建一下玩玩,有一点遗憾的是,在 windows 中用 gdb 单步调试汇编目前还没搞定,在 linux 上很轻松,不过也不影响自己学习研究,毕竟可以用强大的 windbg 和 ollydbg 来实现单步调试,对吧!

与玩好.NET高级调试,你也要会写点汇编相似的内容:

玩好.NET高级调试,你也要会写点汇编

一:背景 1. 简介 .NET 高级调试要想玩的好,看懂汇编是基本功,但看懂汇编和能写点汇编又完全是两回事,所以有时候看的多,总手痒痒想写一点,在 Windows 平台上搭建汇编环境不是那么容易,大多还是用微软的 MASM + DosBox 搭一个 8086 的环境,这玩意距今快 50 年了。 在以

Rancher系列文章-Rancher v2.6使用脚本实现导入集群

概述 最近在玩 Rancher, 先从最基本的功能玩起, 目前有几个已经搭建好的 K8S 集群, 需要批量导入, 发现官网已经有批量导入的文档了. 根据 Rancher v2.6 进行验证微调后总结经验. 1. Rancher UI 获取创建集群参数 访问Rancher_URL/v3/cluster

记一次字符串末尾空白丢失的排查 → MySQL 是会玩的!

开心一刻 今天答应准时回家和老婆一起吃晚饭,但临时有事加了会班,回家晚了点 回到家,本以为老婆会很生气,但老婆却立即从厨房端出了热着的饭菜 老婆:还没吃饭吧,去洗下,来吃饭吧 我洗好,坐下吃饭,内心感动十分;老婆坐旁边深情的看着我 老婆:你知道谁最爱你吗 我毫不犹豫道:你 老婆:谁最关心你? 我:你

LeetCode 周赛 343(2023/04/30)结合「下一个排列」的贪心构造问题

本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问。 大家好,我是小彭。 今天是五一假期的第二天,打周赛的人数比前一天的双周赛多了,难道大家都只玩一天吗?这场周赛是 LeetCode 第 343 场单周赛,如果不考虑第一题摆烂的翻译,整体题目质量还是很不错哒。

Coding:小写一个debugfs

Coding:小写一个debugfs ​ 上一次整活还是在上一个月,写了一个简单的module并且熟悉了module的挂载查看和卸载。这一次我们自然玩一个大的,就是利用linux的debugfs API写一个调试文件系统。 ​ 事实上,底层的API全写好了,我们就是简单的调调API就成的事情! 事先

玩一玩 Ubuntu 下的 VSCode 编程

一:背景 1. 讲故事 今天是五一的最后一天,想着长期都在 Windows 平台上做开发,准备今天换到 Ubuntu 系统上体验下,主要是想学习下 AT&T 风格的汇编,这里 Visual Studio 肯定是装不了了,还得上 VSCode,刚好前几天买了一个小工控机,这里简单记录下 零到一 的过程

玩 ChatGPT 的正确姿势「GitHub 热点速览 v.22.49」

火了一周的 ChatGPT,HG 不允许还有小伙伴不知道这个东西是什么?简单来说就是,你可以让它扮演任何事物,据说已经有人用它开始了颜色文学创作。因

Python——比 Seaborn 更好的相关性热力图:Biokit Corrplot

在 Python 中我们日常分析数据的过程当中经常需要对数据进行相关性分析,相关性热力图(Correlation Heatmap)是我们经常使用的一种工具。通过相关性热力图,我们可以通过为相关性不同的数据使用不同深浅的不同颜色进行标记,从而直观地观察两两数据序列之间的相关性情况——这将有助于我们进一...

Java多线程生成波场靓号

​ 玩区块链,手上没靓号怎么行。用网上的靓号生成器有一定的风险性,思来想去决定自己写一个。首先需要导入波场官方编辑 org.tron.trident utils

我的人工智能与交通运输课程作业:交通流分析示例代码

本文是我上个学期选修的一门人工智能与交通运输课程的一个小作业的实验报告的示例代码部分,源文件为 Jupyter Notebook 格式。这份实验报告是关于对一组微观交通流量数据应用数据分析方法进行简单的研究的,实现了多种不同的交通预测模型并进行了对比。