做了一个java5.0/6.0的反编译工具.随意试用吧.
其实就是做了一个外壳.对class文件修改版本后调用jad来反编译.
调用jad的过程用SW_SHOW显示到前台,目的是为了目标文件中已经存在相同的java文件,比如上一次
已经反编译了一次,没有删除时,jad提示要覆盖,如果在后台没有手工确认jad进程就死在进程列表中了.
最好是在反编译前前目标文件夹清空.
另外没有将临时文件夹自动清空是因为在循环调用ShellExecute时,WaitForSingleObject仍然会产生冲突.
而且程序递归牧举一次临时目录还不如手动在tmp上右键->删除来得方便.
使用的时候把jad5.exe和jad.exe放在相同目录下或将jad.exe放在PATH环境变量中.选择class所在文件夹和目标
文件夹运行即可.
http://www.cnjbb.org/attachment/56/50307/65187/2333/release.rar
以下是主要用到的递归函数.调用时传入用户选择的class文件的目录,也就是函数中的
this->srcDir.
函数中的this->destDir是目标目录.
void Cjad5Dlg::process(CString dir){
WIN32_FIND_DATA fd;
ZeroMemory(&fd, sizeof(WIN32_FIND_DATA));
HANDLE hFile;
hFile = FindFirstFile(dir+"//*",&fd);
do{
if(strcmp(fd.cFileName,".") && (strcmp(fd.cFileName,"..")) && (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){
//是目录但不是"."和".."
process(dir+"//"+fd.cFileName);
}
else if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..")) //不是"."和"..",只能是文件
{
CString srcFile = dir+"//"+fd.cFileName;
CFile cf(srcFile,CFile::modeRead);
if(cf.GetFileName().Find(".class") > 0){ //是class文件
CString path = dir.Mid(this->srcDir.GetLength());
CString destPath = this->destDir + path;
{ //我喜欢把需要即时消失的操作放在{}中
CFileFind cff;
if(!cff.FindFile(destPath)) SHCreateDirectoryEx(NULL,destPath,NULL); //mkdir -p
cff.Close();
}
CString tmpDir = this->destDir +"//tmp"+ path;
{
CFileFind cff;
if(!cff.FindFile(tmpDir)) SHCreateDirectoryEx(NULL,tmpDir,NULL);
cff.Close();
}
CFile cf1(tmpDir + "//" + fd.cFileName,CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
//copy class文件以便修改版本
byte buf[512];
int x = cf.Read(buf,512);
if(x > 8){
buf[7] = 46; //修改为1.4版
cf1.Write(buf,x);
}
while(x = cf.Read(buf,512)){
cf1.Write(buf,x);
}
cf1.Close();
cf.Close();
ShellExecute(NULL,NULL,"jad.exe"," -s java "+tmpDir+"//"+fd.cFileName,destPath,SW_SHOW);
//调用jad返编译
}
else cf.Close();
}
}
while(FindNextFile(hFile,&fd));
}