消息关闭
    暂无新消息!
简单点来说的话,我在使用C++调用一个原本用于java程序的dll文件时,总是被bad_alloc踢出来。
复杂点说的话.....
/***********************************/
现在想要提取一个java程序里面的算法函数原理,用于C++编程。
目标是找到它的算法原代码或者能够让我用黑箱子调用它都可以。
首先用zip对exe进行解压,然后反编译了一个关键class文件,得到目标java函数:
public native short function1(byte[] para1,int para2);

看到native便开始准备黑箱子调用。

用dumpbin.exe处理了与之相关的DLL文件,得到:
          1    0 00005910 Java_function1
我没有这个dll文件的源码,没有h、pdb、lib文件,仅有一个dll。
只知道它本来是供java程序使用,不知道此dll由什么语言写成。
/***********************************/
我的C++环境是VS2015,把dll文件放进cpp文件所在目录,然后尝试动态调用它:

#include<Windows.h>
#include<iostream>
using namespace std;
typedef short (*fit_type)(char[], int);
int main()
{
const char* dllName = "resource_x64.dll";
const char* funName1 = "Java_function1";
char seq1[] = "seq1";
HMODULE hDLL = LoadLibrary(dllName);
if (hDLL != NULL)
{
fit_type function1 = fit_type(GetProcAddress(hDLL, funName1));
if (function1 != NULL)
{
cout << "test start!" << endl;
cout << function1(seq1, 0)<<endl;
}
else
{
std::cout << "Cannot Find Function " << funName1 << std::endl;
}
FreeLibrary(hDLL);
}
else
{
std::cout << "Cannot Find " << dllName << std::endl;
}
return 0;
}

在32位debug下找不到dll文件。
在64位debug下,"test start!"输出到了屏幕上,紧接着在function1被调用的那一行因bad_alloc而被踢了出来。
首先认为可能是数据类型问题。
我尝试了把int改成short,把char改成unsigned char,加上__stdcall,更改seq1的定义方式为char* seq1="seq1"等等众多方法,改过来改过去各种组合,都没有解决问题。
可能是思考方向有问题,研究的方向不太对,但又不知道问题出在哪里,只能继续摸索。
/***********************************/
动态没成功,我想切换静态方法尝试一下:
首先用dumpbin.exe得到dll的export信息,然后修改为ref格式,然后用lib.exe制成lib文件,和dll一起放在cpp文件所在目录。
然后在cpp中写下以下代码,尝试静态调用:

#include<Windows.h>
#include<iostream>
using namespace std;
#pragma comment (lib,"resource_x64.lib")
extern short Java_function1(char seq[], int num);
int main()
{
char seq1[] = "seq1";
cout << "test start!" << endl;
cout << Java_function1(seq1,0)<<endl;
return 0;
}

编译结果:
error LNK2019: 无法解析的外部符号
fatal error LNK1120: 1 个无法解析的外部命令

替换第二行。
extern "C" __declspec(dllexport) short Java_function1(char seq[], int num);

运行结果:
输出了"test start!",然后在Java_function1被调用的那一行因bad_alloc而被踢了出来。
是不是说明这个dll是用C写成的?

修改倒数第二行为
Java_function1("seq1",0);

依然因bad_alloc而被踢了出来。

再改:这次用new来分配内存

#include<Windows.h>
#include<iostream>
using namespace std;
#pragma comment (lib,"resource_x64.lib")
extern short Java_function1(char seq[], int num);
int main()
{
char* seq1 = new char[5];
seq1 = "seq1\0";
cout << "test start!" << endl;
cout << Java_function1(seq1,0)<<endl;
return 0;
}

依然因bad_alloc而被踢了出来。
/***********************************/
无果,决定反汇编/反编译。
ildasm和Reflector都提示这不是.NET,无法反汇编/反编译
考虑过使用java来调用这个dll,然后用C++通过JNI调用java。
不过这样效率是不是有些低?C++模块中存在多线程部分,而且比较要求性能。
我不知道Java_function1中是否存在修改seq1的行为。
/***********************************/
综上:
我三天来的自行思考过程都在上面了,实在没想到好的解决办法。
我的目标是想要提取这个java程序里面的算法函数原理,用于C++编程,无论是找到它的算法原代码或者能够让我用黑箱子调用它都可以。
谢谢~

3个回答

︿ 0
原先java里面所有调用都用的0,并不知道有什么含义。直觉认为还是不要改的好……

好的我去试试depends、DLL Export Viewer和IDA Pro。
程序要移动到其他电脑运行。如果要把C++、JNI和java运行时库都安装才能用,可能不是上策。如果其他方法不行会试试的。

谢谢~
估计要过段时间才能回来发进一步测试结果。