Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C x86 E8和FF调用,如何查找E8移位地址';在飞行中';?基本x86 ASM调用_C_Assembly_X86_Machine Code - Fatal编程技术网

C x86 E8和FF调用,如何查找E8移位地址';在飞行中';?基本x86 ASM调用

C x86 E8和FF调用,如何查找E8移位地址';在飞行中';?基本x86 ASM调用,c,assembly,x86,machine-code,C,Assembly,X86,Machine Code,我在这里处理二进制模糊处理,所以a有一个缓冲区,里面填充了操作码,我使用Linux,所以所有函数调用都使用相同的调用方/被调用方约定,这里没有问题 我的问题是关于E8操作码,这个操作码使用相对地址进行近距离呼叫 我的问题是:我知道打电话的地址,我知道我必须打电话的地址,所以,我如何才能找到我必须在E8电话中输入的轮班地址?这是: signed long src = (signed long)buffer + shift; //get the position where E8 instructi

我在这里处理二进制模糊处理,所以a有一个缓冲区,里面填充了操作码,我使用Linux,所以所有函数调用都使用相同的调用方/被调用方约定,这里没有问题

我的问题是关于E8操作码,这个操作码使用相对地址进行近距离呼叫

我的问题是:我知道打电话的地址,我知道我必须打电话的地址,所以,我如何才能找到我必须在E8电话中输入的轮班地址?这是:

signed long src = (signed long)buffer + shift; //get the position where E8 instruction is
signed long dst = (signed long)srand;          //get the destination position where i want to call (yes, srand(long) function in this case.)
因此,在我的缓冲区中,我有:

buffer[] = "[....]\xE8\xFF\xFA\xFE\x54[.....]"; //example
我需要替换为一个指向srand的有效指针,如何从我拥有的数据中获取相对地址

我只是想我可以用FF指令直接调用,但我不知道怎么做。我无法将地址复制到(比如)$eax,因为我不能在替换中放入超过5个操作码(这将使上面的所有jmp调用都变得异常),而且我不知道是否有方法在5字节内直接调用

因此,如果有人知道如何获得正确的值来替换E8相对移位地址,或者如果有一种方法可以进行某种直接调用,保持与E8调用相同的功能属性,并且只使用5个字节

(询问之前,我试图将FF XX XX XX XX XX XX XX作为实际地址,但它不起作用,x86看起来不像一个电话,它解释为INC(??)和一些随机的东西。我尝试以这种方式替换:

inline void endian_swap(long& x) {
      x = (x>>24) |
          ((x<<8) & 0x00FF0000) |
          ((x>>8) & 0x0000FF00) |
          (x<<24);
}

endian_swap(dst);
endian_swap(src);
unsigned int p = dst - src;
endian_swap(p);
inline void endian_交换(long&x){
x=(x>>24)|
((x8)和0x0000FF00)|
(x我通过以下方法解决了这个问题:

long dst = (long)srand;
long src = ((long)buffer) + shift + 5; //begin of buffer + actual position + this instruction size
long p = dst - src;
p = htonl(p);
然后,我替换了缓冲区上的调用,一切都正常。

我通过执行以下操作解决了此问题:

long dst = (long)srand;
long src = ((long)buffer) + shift + 5; //begin of buffer + actual position + this instruction size
long p = dst - src;
p = htonl(p);

然后我替换了对缓冲区的调用,一切正常。

近调用
jxx
/
近jmp
指令中的相对地址等于要转移控制的目标地址减去
调用
跳转
后的指令地址指令。相对地址是相对于下一条指令的地址,而不是转移控制权的指令。因此,如果指令的地址操作数是相对的,则必须考虑
调用
跳转
指令的长度

一般来说,没有与5字节或更短的
调用
跳转
指令等效的指令

您可以将
jmp
模拟为
push目标地址
+
ret
,但在32位模式下,对于任意目标地址,这两条指令至少会得到1+4+1=6字节。您可以用相同的方式模拟
调用
,但您必须添加另一条
push
调用
指令来放置re打开堆栈上的地址。因此,在这6个字节中再添加5个

有一种“绝对”版本的“jmp”(以及IIRC“call”),它将地址操作数作为由目标偏移量和目标段组成的立即数。这种指令的长度至少为1+4+2=7字节(偏移量为4字节,段选择器为2字节)

如果使用从指定内存位置获取目标地址的
call
jmp
变体(例如
call[ebx]
),则该指令的长度至少为1+1=2字节(操作码+ModR/M字节),但您必须加载一个包含目标地址的内存位置地址的寄存器,这将花费您另外一些1+4=5字节,给您至少7个字节。还有一个变体允许您在寄存器中指定目标地址(例如
jmp ebx
),但同样,由于必须加载寄存器,您至少会输出7个字节


使
调用
/
跳转
指令变短的唯一方法是当目标地址非常接近该指令的地址时(在这种情况下,您可以使用
rel16
形式(使用适当的操作数或地址(我不记得是哪一个)重写前缀)或
rel8
表单(如果可用)或目标地址较小时(在这种情况下,
推送目标地址可以是较短的
推送Ib
或较短的
操作数大小前缀+推送Iw
).

近调用
jxx
/
近jmp
指令中的相对地址等于要转移控制权的目标地址减去紧跟在
调用
跳转
指令之后的指令地址。相对地址与ext指令,而不是传输控制的指令。注意,如果地址操作数是相对的,则必须考虑
调用
跳转
指令的长度

一般来说,没有与5字节或更短的
调用
跳转
指令等效的指令

您可以将
jmp
模拟为
push目标地址
+
ret
,但在32位模式下,对于任意目标地址,这两条指令至少会得到1+4+1=6字节。您可以用相同的方式模拟
调用
,但您必须添加另一条
push
调用
指令来放置re打开堆栈上的地址。因此,在这6个字节中再添加5个

有一种“绝对”版本的“jmp”(以及IIRC“call”),它将地址操作数作为由目标偏移量和目标段组成的立即数。这种指令的长度至少为1+4+2=7字节(偏移量为4字节,段选择器为2字节)

如果您使用从指定内存位置获取目标地址的
call
jmp
变体(例如
call[ebx]
),则该指令的长度至少为1+1=2字节(操作码+ModR/M字节),但您必须用t加载寄存器