• 加密与解密笔记-4.1


    转移指令机器码的形式

    • 位移量 = 目的地址 - 起始地址 - 跳转指令本身的长度
    • 转移指令机器码 = 转移类别机器码 + 位移量

    例子:

    401000 xor eax,eax

    402398 jmp 401000

    • 无条件长转移指令的长度是5字节,机器码是“E9”

    位移量 = 401000h - 402398h - 5h = FFFFEC63h(取后32位
    转移机器码 = E9 + 63 EC FF FF = E9 63 EC FF FF

    数字运算符

    • lea 的意思是“装入有效地址”,它的操作数就是地址,所以lea eax,[addr]就是将表达式的值放入eax寄存器。

    加减法

    lea 指令可以用来替代add和sub指令,如lea edx, dword ptr [ecx+eax+78] 等价于 edx=ecx+eax+78h

    乘法

    乘法运算符一般被编译成mul、imul指令,这些指令的运行速度比较慢。编译器为了提高代码的效率,倾向于使用其他指令来完成同样的计算。如果一个数是2的幂,那么会用左移指令shl来实现乘法运算。另外,加法对于提高3 、 5、 6、 7 、9 等数的乘法运算效率非常有用。例如eax*5 可以写成lea eax,[eax+4*eax]。lea指令可以实现寄存器乘以2,4,8的运算

    除法

    除法运算符一般被编译成div、idiv指令。除法运算的代价是相当高的,大概需要比乘法运算多消耗10倍的CPU时钟。

    • 除法指令需要使用符号扩展cdq,其作用是把eax寄存器中的数视为有符号的数,将其符号位扩展到edx寄存器中,即若eax的最高位是1,则执行后edx的每个位都是1,edx = FFFFFFFFh

    计算字符串的长度

    strlen函数在优化编译模式下的汇编代码如下:

    mov ecx,FFFFFFFF ; 如果看到这一句,程序很可能是要获得字符串的长度
    sub eax,eax
    repnz ;重复串操作,直到ecx=0为止
    scasb ;把AL的内容与edi指向的附加段中的数据逐一比较
    not ecx ;ecx=字符长度+1
    dec ecx ;ecx是真实的长度
    je xxxxxx ;如果ecx=0,意味着字符串的长度为0

    这段代码使用串扫描指令scasb把AL的内容与edi指向的附加段中的字节逐一比较,把edi指向的字符串长度保存在ecx中

    指令修改技巧 P130

    功能指令机器码指令长度(byte)
    替换1字节nop901
    替换2字节nop
    nop
    90
    90
    1
    1
    mov edi,edi8B FF2
    push eax
    pop eax
    50
    58
    1
    1
    inc eax
    dec eax
    40
    48
    1
    1
    jmp xxeb002
    寄存器清零mov eax,00000000hB8 00 00 00 005
    push 0
    pop eax
    6A 00
    58
    2
    1
    sub eax,eax/ xor eax,eax2B C0 / 33 C02
    测试寄存器的值是否为0cmp eax,00000000h
    je _label_
    83 F8 00
    74xx/0F84xxxxxxxx
    3
    2/6
    or eax,eax / test eax,eax
    je _label_
    0B C0 / 85 C0
    74xx/0F84xxxxxxxx
    2
    2/6
    置寄存器为0FFFFFFFFhmov eax,0ffffffffhB8 FF FF FF FF5
    xor eax,eax/ test eax,eax
    dec eax
    33 C0 /2B C0
    48
    2
    1
    stc
    sbb eax,eax
    F9
    2B C0
    1
    2
    转移指令jmp _label_EBxx/E9xxxxxxxx2/5
    push _label_
    ret
    68 xx xx xx xx
    C3
    5
    1
    • 很多指令都针对eax寄存器进行了优化,所以要尽量使用eax寄存器。例如xchg eax,ecx只需要1字节,而使用其他寄存器需要2字节.
  • 相关阅读:
    计算机设计大赛 深度学习猫狗分类 - python opencv cnn
    丑单2023秋招笔试第一题 子串之和(C++ 回溯)
    uni-app连接蓝牙多次回调
    【知识网络分析】耦合网络(bibliographic coupling)
    Oracle查看与修改隐藏参数
    java:代理模式
    如何实现数据库读一致性
    实现抖音视频滑动功能vue3+swiper
    设计模式之外观模式
    Python(1)——基础
  • 原文地址:https://blog.csdn.net/ookami6497/article/details/126734960