python - 如何在 Python 代码中使用来自 IDA 的反编译 C 函数?
问题描述
F5我从IDA的反编译 ( ) 选项中获取了这个 C 函数。
我想在我的 Python 程序中使用它,我怎样才能以最简单的方式做到这一点?
__int64 __fastcall manipulateBeforSend(__int64 a1, int a2)
{
int v2; // w0
__int64 result; // x0
int i; // [xsp+1Ch] [xbp-4h]
for ( i = 0; i < a2 - 3; i += 4 )
*(_DWORD *)(a1 + 4LL * (i / 4)) ^= 0xDEAD1337;// leet? XOR
while ( 1 )
{
result = (unsigned int)a2;
if ( i >= a2 )
break;
LOBYTE(v2) = i & 3;
if ( i <= 0 )
v2 = -(-i & 3);
*(_BYTE *)(a1 + i++) ^= 0xDEAD1337 >> 8 * v2;
}
return result;
}
@Marco Bonelli,你帮了我很多,谢谢!但我不断收到这些错误:
manipulate.c:1:0: warning: -fPIC ignored for target (all code is position independent)
#include <stdint.h>
^
In file included from C:/TDM-GCC-64/x86_64-w64-mingw32/include/crtdefs.h:10:0,
from C:/TDM-GCC-64/x86_64-w64-mingw32/include/stdint.h:28,
from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/stdint.h:9,
from manipulate.c:1:
manipulate.c:4:17: error: two or more data types in declaration specifiers
typedef int64_t __int64;
^
manipulate.c:4:17: error: two or more data types in declaration specifiers
typedef int64_t __int64;
^
manipulate.c:4:1: warning: useless type name in empty declaration
typedef int64_t __int64;
^
解决方案
这是一个“快速”的解决方案:
首先,
typedef
用来定义IDA使用的类型:#include <stdint.h> typedef uint8_t _BYTE; typedef int64_t __int64; typedef uint32_t _DWORD;
您也可以通过“文件”->“生成文件”->“创建 C 头文件”从 IDA 执行此操作,但由于类型很少,因此在这种情况下手动执行此操作更简单。
然后用工作代码替换不需要的宏/值:
__int64 __fastcall manipulateBeforSend(__int64 a1, int a2) // remove __fastcall: __int64 manipulateBeforSend(__int64 a1, int a2) LOBYTE(v2) = i & 3; // convert using a bit mask: v2 = (v2 & 0xffffff00) | (i & 3);
现在有一个问题:正如@Ctx让我们注意到的那样,您的 C 代码正在取消引用第一个参数,很可能是因为它是一个
uint32_t*
指针,而不仅仅是一个int64
:*(_DWORD *)(a1 + 4LL * (i / 4)) // and also *(_BYTE *)(a1 + i++) ^= 0xDEAD1337 >> 8 * v2;
您可能应该花更多时间逆向工程该指针首先用于什么。为了解决这个问题,您可以创建一个假数组并将其添加到您的 C 代码中以使其工作,如下所示:
static uint32_t fakearr[1024 * 1024] = {0}; __int64 manipulateBeforSend(int a2) { uint32_t *a1 = fakearr; // ...
当然,一般来说你可能想要使用一个真正的数组,你可以看看这个答案。
然后将所有(工作)代码放入
.c
文件中:#include <stdint.h> typedef uint8_t _BYTE; typedef int64_t __int64; typedef uint32_t _DWORD; uint32_t fakearr[1024 * 1024] = {0}; __int64 manipulateBeforSend(int a2) { uint32_t *a1 = fakearr; int v2; // w0 __int64 result; // x0 int i; // [xsp+1Ch] [xbp-4h] for ( i = 0; i < a2 - 3; i += 4 ) *(_DWORD *)(a1 + 4LL * (i / 4)) ^= 0xDEAD1337;// leet? XOR while ( 1 ) { result = (unsigned int)a2; if ( i >= a2 ) break; v2 = (v2 & 0xffffff00) | (i & 3); if ( i <= 0 ) v2 = -(-i & 3); *(_BYTE *)(a1 + i++) ^= 0xDEAD1337 >> 8 * v2; } return result; }
将代码编译为共享库:
gcc -fPIC -shared -o mylib.so mylib.c
ctypes
现在您可以使用模块从 Python 加载它:>>> from ctypes import cdll, c_int32 >>> mylib = cdll.LoadLibrary('./mylib.so') >>> mylib.manipulateBeforSend(c_int32(1)) 1
推荐阅读
- html - 我到底怎么把这个 div 放在前面
- python - 将 Python 脚本与不同的 GUI 相结合
- php - 如何在 MacOS XAMPP 中启用 intl 扩展(PHP 版本 7.4.14)
- c# - 如何将定义为基类的变量另存为 json?
- java - Spring ProxyFactoryBean - 有时不调用/丢失拦截器/建议
- sql - 合并列时去掉不必要的空格
- angular - 使配置文件在 staging\prod 环境中可编辑
- javascript - 在 Node Js 中处理动态数量的 Promise
- python - Pandas中爆炸的动态版本?
- javascript - 解构不可迭代实例的无效尝试