#include"stdafx.h"
#include<afxwin.h>
#include<stdio.h>
#include<windows.h>
#include<process.h>
#include<assert.h>
#include<string>
#include<iostream>
#include"CMarkup.h"
#include"md5.h"
#include"rc4.h"
#include<string>
usingnamespacestd;
BOOLGetPackName(
char
* pathXml, charoutPackName[256])
{
CMarkupxml;
boolflag;
CStringpackName;
CStringAppandroidname;
MCD_STRmyapkName;
MCD_STRattribName;
char
* strXML =
"\\AndroidManifest.xml"
;
strcat
(pathXml,strXML);
flag = xml.Load((MCD_STR)pathXml);
if
( FALSE == flag)
{
printf
(
"获得包名失败...\n"
);
returnFALSE;
}
flag = xml.FindElem((MCD_STR)
"manifest"
);
for
(intattribIndex=0;;attribIndex++)
{
attribName=xml.GetAttribName(attribIndex);
if
(attribName.GetLength()!=0)
{
MCD_STRattribVal = xml.GetAttrib(attribName);
packName = attribName.GetString();
if
( 0 ==
strcmp
(packName.GetString(),
"package"
))
{
myapkName = attribVal;
strcpy
(outPackName, attribVal.GetString());
returnTRUE;
}
}
else
break
;
}
returnFALSE;
}
voidStrToHex(
BYTE
*pbDest,
BYTE
*pbSrc, intnLen)
{
charh1,h2;
BYTEs1,s2;
inti;
for
(i=0; i<nLen; i++)
{
h1 = pbSrc[2*i];
h2 = pbSrc[2*i+1];
s1 =
toupper
(h1) - 0x30;
if
(s1> 9)
s1 -= 7;
s2 =
toupper
(h2) - 0x30;
if
(s2> 9)
s2 -= 7;
pbDest[i] = s1*16 + s2;
}
}
int_tmain(intargc, _TCHAR* argv[])
{
charstrAPK[512] = {0};
charapkd[256] =
""
;
charFileDirectory[512] = {0};
chardexDirectory[512] = {0};
charPackName[256] = {0};
BOOLret = FALSE;
structrc4_staterc4_test;
FILE
*fp;
DWORDfileSize = 0;
BYTE
*ptr = NULL;
DWORDDecOffset = 0X1000;
DWORDDecSize = 0X0;
DWORDindex = 0;
stringkey;
printf
(
"请输入要脱壳的apk包路径:\n"
);
scanf
(
"%s"
,strAPK);
if
(NULL == strAPK)
{
printf
(
"路径不能为空!\n"
);
return
-1;
}
strcpy
(apkd,
"java -jar apktool.jar d "
);
strcat
(apkd, strAPK);
CFileapktool(
"apktool.bat"
, CFile::modeCreate | CFile::modeReadWrite);
apktool.Write(apkd,
strlen
(apkd));
apktool.Write(
"\r\n"
,
strlen
(
"\r\n"
));
apktool.Close();
char
* cmd1 =
"apktool.bat"
;
STARTUPINFOsi1;
GetStartupInfo(&si1);
si1.dwFlags = STARTF_USESHOWWINDOW;
si1.wShowWindow = SW_HIDE;
PROCESS_INFORMATIONpi1;
CreateProcess(NULL,
(
LPSTR
)cmd1,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si1,
&pi1);
printf
(
"正在解包apk...\n"
);
WaitForSingleObject(pi1.hProcess,INFINITE);
DeleteFile(
"apktool.bat"
);
printf
(
"解包完成...\n"
);
strncpy
(FileDirectory, strAPK,
strlen
(strAPK)-
strlen
(
".apk"
));
DWORDdwFileAtt;
dwFileAtt = GetFileAttributes(FileDirectory);
if
( dwFileAtt != FILE_ATTRIBUTE_DIRECTORY)
{
printf
(
"apk解包失败!...\n"
);
return
0;
}
printf
(
"apk解包成功!...\n"
);
strcpy
(dexDirectory, FileDirectory);
ret = GetPackName(FileDirectory,PackName);
if
(FALSE == ret)
{
printf
(
"获得包名失败...\n"
);
return
-1;
}
MD5md5(PackName);
key = md5.md5();
strcat
(dexDirectory,
"\\assets\\rsprotect.dat"
);
fp=
fopen
(dexDirectory,
"rb"
);
if
(fp==NULL)
printf
(
"打开文件失败!..."
);
fseek
(fp, 0, SEEK_END);
fileSize =
ftell
(fp);
fseek
(fp, 0, SEEK_SET);
ptr = (
BYTE
*)
malloc
(fileSize);
if
(NULL == ptr)
{
puts
(
"malloc error"
);
}
memset
(ptr,fileSize,0);
fread
(ptr,
sizeof
(
BYTE
), fileSize, fp);
fclose
(fp);
DecSize = *(
DWORD
*)(ptr+12);
index = *(
DWORD
*)(ptr+0x10);
ptr += DecOffset;
if
(0 == DecSize)
{
printf
(
"要解密的dex大小出错\n"
);
return
-1;
}
memset
(&rc4_test,0,
sizeof
(rc4_test));
unsignedcharDecKey[32] = {0};
for
(inti=0; i<32; i++)
{
DecKey[i] = key[i];
}
unsignedcharkey1[32] ={0};
StrToHex(key1, DecKey, 0x10);
fp =
fopen
(
"classes.dex"
,
"wb"
);
if
(NULL == fp)
{
printf
(
"File open error\n"
);
}
for
(inti=0; i<index; i++)
{
init_Key(&rc4_test, key1, 0x10);
rc4_crypt(&rc4_test, ptr, DecOffset);
fwrite
(ptr,
sizeof
(
BYTE
), DecOffset, fp);
ptr+=DecOffset;
}
fclose
(fp);
if
(NULL != ptr)
{
free
(Temp);
ptr = NULL;
Temp = NULL;
}
printf
(
"解密完成!^_^\n"
);
return
0;
}