自学内容网 自学内容网

Linux Reverse(1)-LD_PRELOAD

LD_PRELOAD 是 Linux 系统中的一个环境变量,它允许用户在程序运行时动态地加载共享库。通过设置该环境变量,用户可以指定一个或多个共享库,这些库中的函数将在其他库或程序调用相同函数时优先使用。这在调试、注入、替换函数实现或修改程序行为时非常有用。

使用场景

  1. 函数替换:当你想要替换某个标准库的函数实现时,可以使用 LD_PRELOAD 来加载自定义的库。例如,如果你想要替换 malloc 函数,可以编写一个动态库实现自己的 malloc,然后通过 LD_PRELOAD 指定该库。

  2. 调试和分析:在调试程序时,使用 LD_PRELOAD 可以用来跟踪函数的调用,收集性能数据,或进行故障排查。

  3. 干扰特定应用程序:通过重写程序的某些功能,可以阻止特定的行为或限制程序的访问权限。

基本用法

假设你有一个动态库 mylib.so,它包含了对某些函数的重写,你可以通过以下方式来使用 LD_PRELOAD

LD_PRELOAD=/path/to/mylib.so ./your_program

这里的 /path/to/mylib.so 是你自定义的动态库的路径,./your_program 是你想要运行的程序。这个命令会在 your_program 运行时将 mylib.so 加载到内存中,以便在程序调用相应函数时使用你提供的实现。

例题

  qmemcpy(v21, &unk_400A7E, sizeof(v21));
  v23 = __readfsqword(0x28u);
  v3 = v20;
  for ( i = 9LL; i; --i )
  {
    *(_DWORD *)v3 = 0;
    v3 += 4;
  }
  v18 = 201527;
  v19 = time(0LL);
  do
  {
    for ( j = 0LL; j != 36; ++j )
    {
      v5 = 0LL;
      v6 = time(0LL);
      srand(233811181 - v19 + v6);
      v7 = v20[j];
      v20[j] = rand() ^ v7;
      v8 = (&funny)[j];
      while ( v5 < strlen(v8) )
      {
        v9 = v8[v5];
        if ( (_BYTE)v9 == 105 )
        {
          v22[(int)v5] = 105;
        }
        else
        {
          if ( (_DWORD)v5 && v8[v5 - 1] != 32 )
            v10 = __ctype_toupper_loc();
          else
            v10 = __ctype_tolower_loc();
          v22[(int)v5] = (*v10)[v9];
        }
        ++v5;
      }
      v22[(int)v5] = 0;
      __printf_chk(1LL, byte_400A44, v22);
      sleep(1u);
    }
    --v18;
  }
  while ( v18 );
  v13 = v20;
  __printf_chk(1LL, "KEY: ", v12);
  do
  {
    v14 = (unsigned __int8)*v13++;
    __printf_chk(1LL, "%02x ", v14);
  }
  while ( v13 != v21 );
  v15 = 0LL;
  putchar(10);
  __printf_chk(1LL, "OK YOU WIN. HERE'S YOUR FLAG: ");
  do
  {
    v16 = v21[v15] ^ v20[v15];
    ++v15;
    putchar(v16);
  }
  while ( v15 != 36 );
  putchar(10);
  return 0;
}

整个代码流程主要包括一个循环,该循环负责不断输出 funny 数组中的句子,直到满足某个条件后输出 key,并利用该 key 进行异或运算,从而得到 flag 的值。

考虑到循环次数相对较少,我们可以采取一些方法加速循环的执行。一种有效的方式是手动修改程序以禁止输出字符串(因为 printf 函数的调用会消耗相当多的时间)。同时,我们还可以利用 LD_PRELOAD 技术,重载 sleep() 函数,使其失效,从而显著节省时间。

直到0x4007BD

保存更新一下:

编写代码生成动态链接文件. 

static int t = 0x31337;

void sleep(int sec) {
    t += sec;
}

int time() {
    return t;
}

然后使用命令gcc --shared time.c -o time.so生成动态链接文件. 

然后打开 linux 终端, 运行命令: LD_PRELOAD=./time.so ./hihb_bin100.elf


原文地址:https://blog.csdn.net/lzx13290757580/article/details/142614303

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!