尝试通过 DLL 注入调用进程中的函数,如果可能,需要 IDA 的帮助

逆向工程 艾达 调试 C++
2021-07-01 13:55:05

我正在尝试为名为“ Mech Warrior Online的游戏创建一个机器人我刚刚完成了我的 DLL 注入器,我想将其用作从 MWO 客户端调用函数的方法,例如(触发、移动、环顾四周等...)。

我的问题是我不擅长逆向工程,我正在努力学习教程,但我还没有找到解决我问题的特定教程。

因此,通过使用 IDA 并查看字符串,我发现了这一点: 弦乐窗口

Fire1 到 Fire6 最有可能与射击武器组 1-6 相关。所以如果我点击它,我就会得到这个; 该函数负责一堆东西!

现在这个功能看起来很有趣,似乎可以控制机甲的开/关,跳跃,转弯,油门,武器射击等。

我的问题是我想调用这个函数来发射武器,但我似乎无法弄清楚如何。我做了一些教程,其中我能够注入我的 dll 并通过导出远程调用函数。但是这个功能非常复杂(在我看来)。下面来看看里面:

int __stdcall sub_37FC7C90(int a1)
{
  int result; // eax@5
  int v2; // edx@5
  int v3; // [sp+14h] [bp-4h]@2

  int result; // eax@5

  int v2; // edx@5
  int v3; // [sp+14h] [bp-4h]@2

  if ( !(dword_38CB3580 & 1) )
  {
    dword_38CB3580 |= 1u;
    dword_38CB33F8 = (unsigned int)&unk_389BAE80 | 1;
    LOBYTE(v3) = 1;
    dword_38CB33E8 = (int)"Enabled";
    dword_38CB33EC = 0;
    dword_38CB33F0 = (int)szAgent;
    dword_38CB33F4 = 0;


(*(void (__cdecl **)(_UNKNOWN *, int *))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
      &unk_38CB33FC,
      &v3);


(*(void (__cdecl **)(int *))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB3410 = (unsigned int)&unk_389BAF54 | 1;
    v3 = 0;
    dword_38CB3400 = (int)"Throttle";
    dword_38CB3404 = 0;
    dword_38CB3408 = (int)szAgent;
    dword_38CB340C = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))((((unsigned int)&unk_389BAF54 | 1) & 0xFFFFFFFC) + 0xC))(
      &unk_38CB3414,
      &v3);
(*(void (__cdecl **)(int *))((((unsigned int)&unk_389BAF54 | 1) & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB3428 = (unsigned int)&unk_389BAF54 | 1;
    v3 = 0;
    dword_38CB3418 = (int)"Turn";
    dword_38CB341C = 0;
    dword_38CB3420 = (int)szAgent;
    dword_38CB3424 = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))((((unsigned int)&unk_389BAF54 | 1) & 0xFFFFFFFC) + 0xC))(
      &unk_38CB342C,
      &v3);
(*(void (__cdecl **)(int *))((((unsigned int)&unk_389BAF54 | 1) & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB3440 = (unsigned int)&unk_389BB168 | 1;
    v3 = 0;
    dword_38CB3430 = (int)"TurnTarget";
    dword_38CB3434 = 0;
    dword_38CB3438 = (int)szAgent;
    dword_38CB343C = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))((((unsigned int)&unk_389BB168 | 1) & 0xFFFFFFFC) + 0xC))(
      &unk_38CB3444,
      &v3);
(*(void (__cdecl **)(int *))((((unsigned int)&unk_389BB168 | 1) & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB3458 = (unsigned int)&unk_389BB168 | 1;
    v3 = 0;
    dword_38CB3448 = (int)"LookTarget";
    dword_38CB344C = 0;
    dword_38CB3450 = (int)szAgent;
    dword_38CB3454 = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))((((unsigned int)&unk_389BB168 | 1) & 0xFFFFFFFC) + 0xC))(
      &unk_38CB345C,
      &v3);
(*(void (__cdecl **)(int *))((((unsigned int)&unk_389BB168 | 1) & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB3470 = (unsigned int)&unk_389BAE80 | 1;
    LOBYTE(v3) = 0;
    dword_38CB3460 = (int)"JumpJet";
    dword_38CB3464 = 0;
    dword_38CB3468 = (int)szAgent;
    dword_38CB346C = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
      &unk_38CB3474,
      &v3);
(*(void (__cdecl **)(int *))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB3488 = (int)&unk_389BAE60;
    dword_38CB3478 = (int)"PowerOn";
    dword_38CB347C = 0;
    dword_38CB3480 = (int)szAgent;
    dword_38CB3484 = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 12))(&unk_38CB348C, &v3);
(*(void (__cdecl **)(int *))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB34A0 = (int)&unk_389BAE60;
    dword_38CB3490 = (int)"PowerOff";
    dword_38CB3494 = 0;
    dword_38CB3498 = (int)szAgent;
    dword_38CB349C = 0;
(*(void (__cdecl **)(_UNKNOWN *, int *))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 12))(&unk_38CB34A4, &v3);
(*(void (__cdecl **)(int *))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB34B8 = (int)&unk_389BAE60;
    dword_38CB34A8 = (int)"TogglePower";
    dword_38CB34AC = 0;
    dword_38CB34B0 = (int)szAgent;
    dword_38CB34B4 = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 12))(&unk_38CB34BC, &v3);
(*(void (__cdecl **)(_DWORD))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB34D0 = (int)&unk_389BAE60;
    dword_38CB34C0 = (int)"ToggleWeaponDoors";
    dword_38CB34C4 = 0;
    dword_38CB34C8 = (int)szAgent;
    dword_38CB34CC = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 12))(&unk_38CB34D4, &v3);
(*(void (__cdecl **)(_DWORD))(((unsigned int)&unk_389BAE60 & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB34E8 = (unsigned int)&unk_389BAE80 | 1;
    LOBYTE(v3) = 0;
    dword_38CB34D8 = (int)"Fire1";
    dword_38CB34DC = 0;
    dword_38CB34E0 = (int)szAgent;
    dword_38CB34E4 = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
      &unk_38CB34EC,
      &v3);
(*(void (__cdecl **)(_DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB3500 = (unsigned int)&unk_389BAE80 | 1;
    LOBYTE(v3) = 0;
    dword_38CB34F0 = (int)"Fire2";
    dword_38CB34F4 = 0;
    dword_38CB34F8 = (int)szAgent;
    dword_38CB34FC = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
      &unk_38CB3504,
      &v3);
(*(void (__cdecl **)(_DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB3518 = (unsigned int)&unk_389BAE80 | 1;
    LOBYTE(v3) = 0;
    dword_38CB3508 = (int)"Fire3";
    dword_38CB350C = 0;
    dword_38CB3510 = (int)szAgent;
    dword_38CB3514 = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
      &unk_38CB351C,
      &v3);
(*(void (__cdecl **)(_DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB3530 = (unsigned int)&unk_389BAE80 | 1;
    LOBYTE(v3) = 0;
    dword_38CB3520 = (int)"Fire4";
    dword_38CB3524 = 0;
    dword_38CB3528 = (int)szAgent;
    dword_38CB352C = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
      &unk_38CB3534,
      &v3);
(*(void (__cdecl **)(_DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB3548 = (unsigned int)&unk_389BAE80 | 1;
    LOBYTE(v3) = 0;
    dword_38CB3538 = (int)"Fire5";
    dword_38CB353C = 0;
    dword_38CB3540 = (int)szAgent;
    dword_38CB3544 = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
      &unk_38CB354C,
      &v3);
(*(void (__cdecl **)(_DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB3560 = (unsigned int)&unk_389BAE80 | 1;
    LOBYTE(v3) = 0;
    dword_38CB3550 = (int)"Fire6";
    dword_38CB3554 = 0;
    dword_38CB3558 = (int)szAgent;
    dword_38CB355C = 0;
(*(void (__cdecl **)(_UNKNOWN *, _DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 0xC))(
      &unk_38CB3564,
      &v3);
    (*(void (__cdecl **)(_DWORD))((((unsigned int)&unk_389BAE80 | 1) & 0xFFFFFFFC) + 4))(&v3);
    dword_38CB3568 = 0;
    dword_38CB356C = 0;
    dword_38CB3570 = 0;
    dword_38CB3574 = 0;
    dword_38CB357C = 0;
    dword_38CB3578 = (int)&unk_389BAEA0;
    atexit(sub_386F1FC0);
  }
  if ( !(dword_38CB3580 & 2) )
  {
    dword_38CB3580 |= 2u;
    dword_38CB33D4 = 0;
    dword_38CB33D8 = 0;
    dword_38CB33DC = 0;
    dword_38CB33E0 = 0;
  }
  result = a1;
  v2 = *(_DWORD *)(a1 + 8);
  *(_DWORD *)(a1 + 12) = szAgent;
  *(_DWORD *)a1 = &dword_38CB33E8;
  *(_DWORD *)(a1 + 4) = &dword_38CB33D4;
  *(_DWORD *)(a1 + 8) = v2 & 0xFFFFF01F | 0x11;
  return result;
}

对不起,我知道它很乱,但功能相当大。

任何人都可以告诉我如何Fire1从我的 DLL 中调用 let's say 我现在真的不知道该怎么做。我知道我完全不知所措,但我想学习!

感谢任何愿意伸出援手的人!干杯

1个回答

此函数初始化一个全局对象,如果它尚未初始化,并将其返回给调用者。

对象似乎有一个结构数组,该结构描述了您认为玩家可以采取的行动。看起来初始化的一部分是为每个结构实例设置一个可调用函数。

以下是我认为您接下来可以做的几件事:

  1. 理解用每个动作结构初始化的那些函数。我建议您在每个函数上设置一个断点,并查看它在玩家执行该操作后是否实际触发,以验证该函数确实参与了该操作。

  2. 查找对对象地址范围的所有引用并了解该对象的用法。

  3. 放弃这些字符串(因为它们通常不容易与游戏中的动作本身相关),而是按照按键操作,如本答案中所述

这个问题也可能有用。