Stay Hungry.Stay Foolish.
学习使用GCC内联汇编

最新玩逆向,发现分析别人的算法实在是难,于是就打算直接把IDA反汇编出来的代码用内联汇编来玩,GCC的内联汇编语法可以参考这里

初学

加法函数

#include <stdio.h>

int
main(void)
{
    int a = 1, b = 2, c;
    __asm__ 
    ("movl %1, %%eax\t\n" 
     "movl %2, %%ebx\t\n" 
     "addl %%ebx, %%eax\t\n"
     "movl %%eax, %0"
     :"=r"(c)               /* output */ 
     :"r"(a),"r"(b)         /* input */
     :"%eax", "%ebx"        /* clobbered register */
    );
    printf("%d\n", c);
}

上面的内联汇编代码实现int add(int a, int b)功能。注意一下几点

  1. 内联汇编里面的寄存器用两个%%,操作数s使用1个%
  2. 第一个”:”分割符号之后是输出变量,前面加个”=”表面变量只写
  3. 第二个”:”分割符号之后是输入变量,如果有多个用逗号分割,
  4. 第三个”:”分割符号告诉GCC前面不要使用这些寄存器保存值,内联汇编可能会修改掉这些值。
  5. a,b,c分别对应内联汇编里面的%1, %2, %0操作符号(a,b,c是c代码里面声明的变量)。

swap函数

#include <stdio.h>

int
main(void)
{
    int a = 101, b = 102;
    __asm__ 
    ("movl %2, %%eax\t\n" 
     "movl %3, %%ebx\t\n" 
     "xchg %%eax, %%ebx\t\n"
     "movl %%eax, %0\t\n"
     "movl %%ebx, %1"
     :"=r"(a), "=r"(b)
     :"r"(a),"r"(b)
     :"%eax", "%ebx"
    );
    printf("%d\t%d\n", a, b);
}

更加装逼的,可以把内联的汇编定义为宏

#include <stdio.h>

#define swap(a, b)           \
    __asm__                  \
    ("movl %2, %%eax\t\n"    \
     "movl %3, %%ebx\t\n"    \
     "xchg %%eax, %%ebx\t\n" \
     "movl %%eax, %0\t\n"    \
     "movl %%ebx, %1"        \
     :"=r"(a), "=r"(b)       \
     :"r"(a),"r"(b)          \
     :"%eax", "%ebx"         \
    );  

int
main(void)
{
    int a = 101, b = 102;
    swap(a, b);
    printf("%d\t%d\n", a, b);
}

精简版本

#include <stdio.h>

#define swap(a, b)           \
    __asm__                  \
    ("movl %2, %1\t\n"       \
     "movl %3, %0\t\n"       \
     :"=r"(a), "=r"(b)       \
     :"r"(a),  "r"(b)        \
    );  

int
main(void)
{
    int a = 101, b = 102;
    swap(a, b);
    printf("%d\t%d\n", a, b);
}
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证
评论
2019-01-13 16:23:09

Amoxicillin K Clav 875mg Original Kamagra 100mg Oral Jelly <a href=http://cialiviag.com>cialis tablets for sale</a> Boil Amoxicillin Cialis Mg Filmtabletten