自修改代码[C++]

Gog*_*a70 5 c++ self-modifying

我正在阅读关于自修改代码的密码破解者期刊文章,并且有以下代码片段:

void Demo(int (*_printf) (const char *,...))
{ 
      _printf("Hello, OSIX!n"); 
      return; 
} 
int main(int argc, char* argv[]) 
{ 
  char buff[1000]; 
  int (*_printf) (const char *,...); 
  int (*_main) (int, char **); 
  void (*_Demo) (int (*) (const char *,...)); 
  _printf=printf; 
  int func_len = (unsigned int) _main ­- (unsigned int) _Demo; 
  for (int a=0; a<func_len; a++) 
    buff[a] = ((char *) _Demo)[a]; 
  _Demo = (void (*) (int (*) (const char *,...))) &buff[0]; 
  _Demo(_printf); 
  return 0; 
}
Run Code Online (Sandbox Code Playgroud)

这段代码应该在堆栈上执行Demo().我理解大部分代码,但是他们分配'func_len'的部分让我困惑.据我所知,他们从另一个随机指针地址中减去一个随机指针地址.

有人在意解释?

Jon*_*ler 7

代码依赖于编译器中函数布局的知识 - 这可能与其他编译器不可靠.

func_len行一旦被纠正以包括-最初缺失的行,就Demo通过从地址中减去地址_Demo(应该包含起始地址Demo())来确定函数的长度(该地址_main应该包含起始地址)main()).这被假定为函数的长度,Demo然后按字节方式复制到缓冲区中buff.buff然后将地址强制转换为函数指针,然后调用该函数.但是,既然实际上都_Demo没有_main初始化,那么代码就是极端错误.另外,还不清楚a unsigned int是否足以准确地保持指针; 演员应该是uintptr_t来自<stdint.h><inttypes.h>.

如果错误是固定的,如果关于代码布局的假设是正确的,如果代码是与位置无关的代码,并且如果没有防止执行数据空间的保护,则这是有效的.它不可靠,不便携,不推荐.但它确实说明,如果它有效,代码和数据非常相似.

我记得在两个进程之间拉一个类似的特技,将一个函数从一个程序复制到共享内存,然后让另一个程序从共享内存中执行该函数.这是大约四分之一世纪以前的事情,但这种技术与它所尝试的机器相似并且"有效".我从来不需要使用这种技术,谢天谢地!


ybu*_*ill 5

此代码使用未初始化的变量_main_Demo,所以它不能在一般的工作.即使它们意味着不同的东西,它们也可能假设在内存中有一些特定的函数排序.

我的意见:不要相信这篇文章.