aswcy815174418 发表于 2021-3-27 10:11

硬编码写进数据区报错

VS2019环境
两数相加硬编码:
55               
8B EC            
81 EC C0 00 00 00
53               
56               
57               
8D BD 40 FF FF FF
B9 30 00 00 00   
B8 CC CC CC CC   
F3 AB            
8B 45 08         
03 45 0C         
5F               
5E               
5B               
8B E5            
5D               
C3
               

bester 发表于 2021-3-27 10:50

这种是数据区内存没有执行权限,这块只有读写权限,但是没有执行权限

aswcy815174418 发表于 2021-3-27 12:23

bester 发表于 2021-3-27 10:50
这种是数据区内存没有执行权限,这块只有读写权限,但是没有执行权限

我这不就是读取执行嘛{:1_896:}

lyl610abc 发表于 2021-3-27 13:34

本帖最后由 lyl610abc 于 2021-3-27 13:38 编辑

上面的大佬说得没错,是内存权限不足的原因
我补充一下正确的写法:
#include<stdio.h>
#include<windows.h>
int main(int argc, char* argv[])
{
      unsigned char byte[] = {
      0x55,
      0x8B,0xEC,
      0x81,0xEC,0xC0,0x00,0x00,0x00,
      0x53,
      0x56,
      0x57,
      0x8D,0xBD,0x40,0xFF,0xFF,0xFF,
      0xB9,0x30,0x00,0x00,0x00,
      0xB8,0xCC,0xCC,0xCC,0xCC,
      0xF3,0xAB,
      0x8B,0x45,0x08,
      0x03,0x45,0x0C,
      0x5F,
      0x5E,
      0x5B,
      0x8B,0xE5,
      0x5D,
      0xC3
      };

      //申请内存,该内存的属性为可执行 可读可写
      LPVOID p = VirtualAlloc(NULL, sizeof(byte), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
      //类型转换为指针函数
      int (*add)(int x, int y) = (int(*)(int, int))p;
      //将硬编码写入申请的有权限的内存中
      WriteProcessMemory(INVALID_HANDLE_VALUE, (LPVOID)add, (BYTE*)byte, sizeof(byte), 0);
      //调用函数
      int result = add(1, 2);
      //输出结果
      printf("%d\n", result);
      getchar();
      return 0;
}

附上运行结果:

bester 发表于 2021-3-27 13:46

lyl610abc 发表于 2021-3-27 13:34
上面的大佬说得没错,是内存权限不足的原因
我补充一下正确的写法:
#include


大佬 你是不是偷懒,在指针系列没有讲指针函数的强制转换啊,一开始我以为楼主的写法错了,但是看不懂(int(*)(int, int)) &byte,能不能解释一下为什么可以写(*) 或者 能不能写成int* (void*)(int,int)=&byte

lyl610abc 发表于 2021-3-27 13:57

本帖最后由 lyl610abc 于 2021-3-27 14:02 编辑

bester 发表于 2021-3-27 13:46
大佬 你是不是偷懒,在指针系列没有讲指针函数的强制转换啊,一开始我以为楼主的写法错了,但是看不懂(in ...
{:301_986:}容我为自己辩解(狡辩)一下,我不是偷懒
你也看到这里涉及到了内存属性、内存分配还有WIN32部分的内容
所以我是打算放到后面的时候再补充
(int(*)(int, int)) &byte就是一个强制类型转换而已,和普通的类型转换并没有什么不同,只不过转换的类型为指针函数而已
为什么这么写?
因为(int(*)(int, int))就是指针函数的类型,这个指针函数:指向函数的指针,这个函数的返回值为int,参数为2个int
关于查看变量的类型,我在先前的指针系列中的指针二也有提到用typeid(变量).name()来查看
运行结果:
页: [1]
查看完整版本: 硬编码写进数据区报错