首页 文章

自修改代码[C]

提问于
浏览
5

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

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; 
}

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

有人在乎解释?

2 回答

  • 7

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

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

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

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

  • 5

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

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

相关问题