参考リンク:
https://blog.csdn.net/cjbbdd/article/details/103583764
リンクに記載されていない、使用上の注意点:
1. NDK のバージョン:
使用される ndk バージョンは r9d で、ダウンロード アドレスは次のとおりです。
- Windows:https://dl.google.com/android/ndk/android-ndk-r9d-windows-x86_64.zip
- Linux:https://dl.google.com/android/ndk/android-ndk-r9d-linux-x86_64.tar.bz2
参照ブログには、ほとんどの ndk バージョンのダウンロードがあります: Android 開発用の NDK 関連バージョンのダウンロード リンク
2. パッケージ名を取得する
参考ブログ:Android apkのパッケージ名とエントリの取得方法
使用される主なコマンドは次のとおりです。
aapt dump badging <*.apk的完整路径>。(可以直接将.apk文件拖拽到命令行中,可直接获取.apk的完整路径)
3.シミュレーター
参考ブログはThunderboltシミュレーターを使っています.Yeghenシミュレーターを使っています.ブログリンクでインストールしたXposedInstallerはYeghenシミュレーターでは正常に動作しません.実は一般的なシミュレーターにはXposedInstallerのダウンロードアドレスがあり,対応するバージョンをダウンロードするだけです. . Yeshen Simulator はゲーム センターにあります。検索ボックスに XposedInstaller と入力してダウンロードします。
Raiden Simulator のいくつかの問題:
(1) adb サービスを実行するとエラーが表示される
adb server version (36) doesn't match this client (41); killing...
エラーメッセージから、SDKのadbバージョンとYeshen Simulatorのadbバージョンの不一致が原因です。
解決
- AndroidSDK\platform-tools の下にある adb.exe をデスクトップに割り当て、名前を nox_adb.exe に変更します。
- 夜神シミュレーターのnox_adb.exeをnox_adb_old.exeに変更
- デスクトップ上の nox_adb.exe を Yeshen シミュレーターの bin パスにコピーします。
- ナイトシミュレーターを再起動する
参考ブログ: adb server version (36) does not match this client (41); kill... を解決する
(2) AndroidStdio DDMS が Yeshen Simulator に接続
AndroidStdio で DDMS を開く方法: Tools——>Android——>android devices monitor
問題: DDMS を開いた後、接続されているデバイスが表示されない場合。
解決策:①
最初にYeshen Simulatorを起動します
② 次に、cmd コマンドを実行し、cd で Yeshen のインストール ディレクトリ (bin フォルダーの下) に移動し、コマンド nox_adb.exe connect 127.0.0.1:62001 を実行するか、Yeshen シミュレーターのインストール ディレクトリ (bin フォルダー) を直接開きます。 address bar adb Enter キーを押してから、コマンド nox_adb.exe connect 127.0.0.1:62001 を実行するか、環境変数パスに Yeshen シミュレーターのインストール ディレクトリ (bin フォルダー) のパスを構成し、cmd コマンド nox_adb を直接実行します。 exe connect 127.0.0.1: 620010 エミュレータに接続する
③Yeghenシミュレーターが表示されない場合は、adb後にYeghenシミュレーターを再起動してください
④ 注: Yeshen エミュレーターは他のエミュレーターと互換性がないため、他のエミュレーターを開かないでください (複数の異なる種類のエミュレーターを開くと、同時に複数の adb.exe プロセスが開き、システムは 1 つの adb.exe しか認識できません)。
参照リンク: Yeshen Simulator への AndroidStdio DDMS 接続
4. AndroidEagleEye ソース コードの変更:
(1) ログに「メモリ マップを読み取れません」というエラー メッセージが表示される場合は、メモリ マップをロードするためのキャッシュが小さすぎることが原因として考えられます。マップ データがキャッシュ サイズを超える可能性があります。
static int load_memmap(pid_t pid, struct mm *mm, int *nmmp)
{
char raw[80000]; // increase this if needed for larger "maps"
// 将80000修改为更大的缓存大小,80000->800000
// ...
}
(2) ログに「シンボル テーブルを読み取れません」というエラーが報告されている場合は、libc.so シンボル セットをロードする open 関数がファイルの読み取りに失敗した可能性があります。実際のシステム ファイルは存在し、メモリ マップは「/ system/lib/ arm/nb/libc.so '、しかし open 関数はファイルの読み取りに失敗し、strerror(errno) を呼び出すと、エラー メッセージはファイルが存在しない (No such file or directory) であり、具体的な理由は知らない、
R11 Plus:/ # ll /system/lib/arm/nb/libc.so
-rw-r--r-- 1 root root 1011828 2021-10-23 01:05 /system/lib/arm/nb/libc.so
ルート ディレクトリを表示し、次のリンクを見つけます。
R11 Plus:/ # ll /
total 1832
dr-xr-xr-x 17 root root 0 2023-02-23 18:07 acct
lrwxrwxrwx 1 root root 50 1970-01-01 08:00 bugreports -> /data/user_de/0/com.android.shell/files/bugreports
drwxrwx--- 6 system cache 4096 2021-09-18 10:26 cache
lrwxrwxrwx 1 root root 13 1970-01-01 08:00 charger -> /sbin/healthd
dr-x------ 2 root root 40 1970-01-01 08:00 config
lrwxrwxrwx 1 root root 17 1970-01-01 08:00 d -> /sys/kernel/debug
drwxrwx--x 34 system system 4096 2021-09-18 10:26 data
-rw-r--r-- 1 root root 959 1970-01-01 08:00 default.prop
drwxr-xr-x 17 root root 4020 2023-02-23 18:07 dev
lrwxrwxrwx 1 root root 11 1970-01-01 08:00 etc -> /system/etc
-rw-r--r-- 1 root root 77090 1970-01-01 08:00 file_contexts.bin
-rw-r----- 1 root root 396 1970-01-01 08:00 fstab.qcom
-rwxr-x--- 1 root root 1490548 1970-01-01 08:00 init
-rwxr-x--- 1 root root 887 1970-01-01 08:00 init.environ.rc
-rwxr-x--- 1 root root 3689 1970-01-01 08:00 init.qcom.rc
-rwxr-x--- 1 root root 25284 1970-01-01 08:00 init.rc
-rwxr-x--- 1 root root 582 1970-01-01 08:00 init.superuser.rc
-rwxr-x--- 1 root root 9283 1970-01-01 08:00 init.usb.configfs.rc
-rwxr-x--- 1 root root 5716 1970-01-01 08:00 init.usb.rc
-rwxr-x--- 1 root root 411 1970-01-01 08:00 init.zygote32.rc
lrwxrwxrwx 1 root root 10 2023-02-23 18:07 lib -> system/lib
下部に lib と system/lib 間のリンクがあります.これは Android システムとその下の Linux の間の問題であると推測されるため、パスはソース コードの load_symtab 関数で置き換えられます
static symtab_t load_symtab(char *filename)
{
int fd;
symtab_t symtab;
symtab = (symtab_t) xmalloc(sizeof(*symtab));
memset(symtab, 0, sizeof(*symtab));
// 增加的替换路径代码 开始
if (strncmp("/system/lib", filename, 11) == 0) {
char strtmp[1024] = "/lib";
strncpy(strtmp + 4, filename + 11, strlen(filename) - 11);
memset(filename, 0, strlen(filename));
strncpy(filename, strtmp, sizeof(strtmp));
}
// 增加的替换路径代码 结束
fd = open(filename, O_RDONLY);
if (0 > fd) {
return NULL;
}
if (0 > do_load(fd, symtab)) {
log("Error ELF parsing %s\n", filename)
free(symtab);
symtab = NULL;
}
close(fd);
return symtab;
}
5. ブログ投稿を参照してください。無効化を避けるために、直接コピーしてください。侵害がある場合は、通知して削除してください。
参考リンク:cocos2dx xxtea リバース エンジニアリング lua スクリプトとリソース ファイル_cjbbdd のブログ - CSDN blog_xxtea lua
ツールの準備:
IDA Pro 7、正規版を使用するか、x バージョンを使用するかは、自分で決めることができます。
Android SDK と NDK
AndroidEagleEye のリンク アドレスは次のとおりです。 AndroidEagleEye
AndroidEagleEye には XposedInstaller が必要です。Baidu から直接最新バージョンをダウンロードします。私は誰もが怠け者であることを知っているので、リンクは次のとおりです: XposedInstaller,
an Andrid phone or Thunderbolt emulator after ROOT OK
, それでは本題に入りましょう. この記事では、ネチズンから送られてきた jjw.apk という QP ゲームを使用しています。
APK ファイルを解凍し、libs/armeabi/libcocos2d.so ファイルと、assets ディレクトリの下の src および res フォルダーを見つけます。これは、復号化する必要があるものです。この APK は xxtea 暗号化を使用していることがわかりました。右クリックして luac ファイルを開くと、次のように表示されます。
Luac コードの内容
ここで、lua で暗号化された署名が赤い丸の内容であることがわかります。まず、それを記録するファイルを見つけて、後で使用します。
次に、任意の png 画像を開き、次のように表示します。
PNG リソース コンテンツ
また、png リソースの署名を見つけ、ファイルを見つけて記録しました。
IDA Pro 7 を起動し、libcocos2dlua.so をツールにアップロードします。このことは少し行き詰まると推定されます. IDA が so ファイルの分析を終了するのを待ってから, 関数ビューを見つけます. このビューが IDA に存在しないことがわかった場合は, View->Open SubViews- をクリックしてください. >それを開く機能。以下に示すように:
IDA 関数ビュー
最初に lua スクリプトを扱いましょう。cocos2dxlua を使用したことがある人なら誰でも、エンジンが初めて lua スクリプトをロードするときに cocos2d::LuaStack::executeScriptFile メソッドを呼び出すことを知っているので、[関数名] ウィンドウで任意のメソッドを選択し、CTRL + F を押して検索します。関数名の下に入力ボックスが表示され、入力ボックスに LuaStack と入力すると、図に示すように次の結果が得られます。
LuaStack の結果を検索
結果
の分析を開始したところ、最初に、上の図に示されている cocos2d::LuaStack::hfhgjrhrhfxs という非常に奇妙な文字化けメソッドを見つけたので、このメソッドをダブルクリックしました。cocos2dx はオープン ソース エンジンであるため、正式な名前が固定されているため、このメソッドはカスタム メソッドである必要があります。
hfhgjrhrhfxs メソッド
これは大きな頭に違いないので、ここで F5 キーを押すと、次のようになります。
逆コンパイル後の hfhgjrhrhfxs メソッドは
特に何も見えないので、とりあえず無視しておきましょう 上記の操作で、一時的にメソッドやクラスを見つけて、あるメソッドを逆コンパイルすることを学びました。次に加速を始めます。
関数ウィンドウに戻り、cocos2d::LuaStack::executeScriptFile メソッドをダブルクリックして逆コンパイルします。一番下までドラッグすると、探していたメソッド cocos2d::LuaStack::luaLoadBuffer が見つかりました。以下に示すように:
luaLoadBuffer メソッドの呼び出しを見つけます.
この場所でメソッドをダブルクリックしてフォローアップします.今日のマスターを見つけました:
xxtea 暗号化の使用 [
関数] ウィンドウ以外のすべてのウィンドウを閉じてから、xxtea_decrypt メソッドを検索し、ダブルクリックして、次のコンテンツを開きます。
xxtea_decrypt メソッドのアセンブリ
赤いボックスの内容を記録します。これは必要なメソッドの特定の名前です。後で HOOK で使用する必要があります。
赤いボックスの下に 2 行の緑のメソッドがあり、このメソッドを呼び出す場所があることを示しています。 cocos2d::LuaStack::luaLoadBuffer(lua_State *,char const*,int,char const*)+D0↑p をダブルクリックします。 ..入ってチェックしてください。
LuaStack::luaLoadBuffer で xxtea_decrypt が呼び出される場所
このメソッドのパラメーターの型は、unsigned char*、unsigned int、unsigned char*、unsigned int、unsigned int* であることがわかりました。記録します。
LuaStack でメソッドを見つけたところ、ボスの cocos2dx の setxxteaKeyAndSign メソッドが存在しないことがわかったので、次の方法でしか復号化されたキーを強制的に取得できません。
この記事では、Thunderbolt シミュレーターを使用します。Thunderbolt シミュレーターを開き、jjw.apk をインストールします。
ダウンロードした EagleEye を開き、EagleEye.apk を見つけてインストールします。
Xposed Installer をインストールし、Xposed フレームワークをアクティブにしてから、エミュレーターを再起動します。インストールが完了すると、次のインターフェイスが表示されます。
Xposed は、フレームワークをインストールしてアクティブにし
、左上隅のメニュー ボタンをクリックして、[Modules] を選択し、EagleEye にチェックを入れて、Xposed を再起動します。
EagleEye を有効にする
EagleEye\jni\hooks\hook_apis.c ファイルを見つけて、編集用に開きます。
これで HOOK を必要とするメソッドに関するすべての情報がわかりました。次に、このファイルの末尾に独自の HOOK API を記述する必要があります。
unsigned char* eagle_xxtea_decrypt(unsigned char* a,unsigned int a1,unsigned char* b,unsigned int b1,unsigned int* c);
HOOK_INFO custom_hook_info_xxtea_decrypt = {
{},"libcocos2dlua","_Z13xxtea_decryptPhjS_jPj",eagle_xxtea_decrypt,eagle_xxtea_decrypt};
unsigned char* eagle_xxtea_decrypt(unsigned char* a,unsigned int a1,unsigned char* b,unsigned int b1,unsigned int* c) { unsigned char* (
* orig_xxtea_decrypt)(unsigned char* a,unsigned int a1,unsigned char* b ,unsigned int b1,unsigned int* c); struct hook_t eph = custom_hook_info_xxtea_decrypt.eph; orig_xxtea_decrypt = (void*)eph.orig; LOGI("###########カミング xxtea_decrypt キー: %s",b); hook_precall(&eph);
unsigned char* res = orig_xxtea_decrypt(a,a1,b,b1,c);
hook_postcall(&eph);
return res;
}
少しややこしいかもしれませんが、問題ありません。 EagleEye の中国語ドキュメント。このコードの目的は、必要な復号化キーを Android コンソールに出力することです。
EagleEye の Android プロジェクトのルート ディレクトリを入力します。
EagleEye の Android プロジェクトは、ディレクトリを変更して
jni ディレクトリに入り、ndk-build によってコンパイルされます。
次に、ルート ディレクトリ、native_lib.config に新しい構成ファイルを作成します。このファイルは、EagleEye にそのファイルを HOOK に伝えます。内容は次のとおりです。
native_lib.config
この so ファイルの名前は、解凍した apk 内の so ファイルの名前です。
次に、コンパイルされた EagleEye の so ファイルと native_lib.config ファイルをシミュレーターにプッシュする必要があります。
新しい doPush.bat バッチを作成します。内容は次のとおりです。
adb push libs/armeabi/libeagleeyenative.so /data/data/com.mindmac.eagleeye/lib/libeagleeyenative.so
adb push native_lib.config /data/data/com.jiujiuwan.jjw/native_lib.configこの操作の目的
は
libeagleeyenative.so ファイルをインストール済みの EagleEye にプッシュし、native_lib.config 構成ファイルをクラックする必要がある jjw.apk ディレクトリにプッシュします。
このパッケージ名の由来については、皆さんご存知だと思いますので割愛させていただきます。
次に、コマンド ラインを開き、jjw の userId を見つけます。
jjw の userId を取得し
、jjw.apk のインストール パスを入力します。native_lib.config プロパティが読み取り可能であることを確認し、EagleEye のシステム プロパティを設定します。
ファイルの読みやすさと EagleEye のプロパティを設定し、
EagleEye と Xposed を再起動します。Android SDK ルート ディレクトリ ->tools->monitor.bat を見つけて、Android Device Monitor が開き、エミュレーターのログ出力が検出されるまで待ちます。
Android Device Monitor
は良好です。jjw.apk を起動して、ログ出力を確認します。
HOOK ログ
2 つの異なるログ出力が表示されますが、問題ありません。この記事の前にもう 1 つのメソッドを HOOK しました. 結局、この apk の作成者は luaload プロセスを再度変更したため、見つけやすくなりました. そこで、前のトラックをたどって、彼が変更した lua_loadx メソッドを見つけたので、 ,フックを与えました:
int eagle_lua_loadx(int a1, int a2, int a3, const char *a4, int a5);
HOOK_INFO custom_hook_info_lua_loadx = {
{},"libcocos2dlua","lua_loadx",eagle_lua_loadx,eagle_lua_loadx};
int eagle_lua_loadx(int a1, int a2, int a3, const char *a4, int a5){ int (*orig_lua_loadx)(int a1, int a2, int a3, const char *a4, int a5); struct hook_t eph = custom_hook_info_lua_loadx.eph; orig_lua_loadx = (void*)eph.orig; LOGI("###########フックに来る lua_loadx with string: %s",a4); hook_precall(&eph); int 結果 = orig_lua_loadx(a1,a2,a3,a4,a5); hook_postcall(&eph); 結果を返します。それで、今それを見て、ロードされたluaファイル名を出力しました。次に、一番下の長い方が lua キーで、短い方は png でなければなりません。
次にやらなければならないことは、Baidu を開いて xxtea ファイルを解読できるものを検索することです. 私は怠け者なので、たくさんの解読コードを書きたくありません. ポータルには次のものが付属しています: XXTEA 解読ツール
XXTEA 復号化ツール
よし、結果をお見せしましょう:
PNG復号化後
復号化された LUA コード
以上が本日のチュートリアルです。ご覧いただきありがとうございます。