如何移除终端第三行(执行add [eax],al时)生成的空字节?
解决
add [eax],al生成空字节的问题 嘿,这个问题我之前在调试shellcode和汇编程序的时候碰到过,得先明确你说的“空字节”是指指令本身的机器码里带0x00,还是执行指令后目标内存地址出现了0x00字节?我分两种情况给你说清楚解决方案:
一、如果是指令机器码里的空字节(比如shellcode需要避开空字节)
add [eax],al的x86机器码是00 00——第一个字节是操作码00(表示8位加法,目标是内存操作数,源是寄存器),第二个字节是ModRM字节00(指定用eax作为基址寄存器,无偏移)。这俩字节都是0x00,如果你的场景里不能出现空字节(比如shellcode里0x00会被当作字符串终止符截断),可以用等价的指令组合绕开:
- 换用其他基址寄存器来执行加法,比如ebx:
这段代码和push eax ; 机器码 50,无空字节 pop ebx ; 机器码 5B,无空字节 add [ebx], al ; 机器码 00 03,无空字节!add [eax],al功能完全一样——把al的值加到eax指向的内存字节里,但机器码里没有0x00,完美避开空字节问题。
二、如果是执行指令后目标内存出现空字节
要是执行add [eax],al后,[eax]指向的内存变成了0x00,那原因很直观:
- 8位加法会自动截断溢出,假设执行前
[eax]的值是X,执行后结果是(X + al) & 0xFF。如果结果是0x00,要么是X + al刚好等于0x100(溢出后截断为0),要么是X和al的有符号值相加为0。 - 解决方法也很直接:
- 先检查
al的值,如果是0的话,执行加法也不会改变[eax]的值,要是原本[eax]就是空字节,那执行后还是空字节——这种情况可以直接跳过加法:test al, al jz skip_add ; al为0时跳过加法 add [eax], al skip_add: - 如果业务逻辑要求相加后不能是空字节,可以在执行加法前预判结果,提前处理:
mov cl, byte ptr [eax] add cl, al jz skip_add ; 预判结果为空字节,跳过执行 add [eax], al skip_add:
- 先检查
内容的提问来源于stack exchange,提问作者Pushpam Kumar
相关产品推荐
相关产品推荐

