本題的參考鏈接:https://share.weiyun.com/5Xg2b7v
其實拿到這個題我就感覺在哪里看過,后來想想是在旺仔那里看到的,以下是旺仔寫的分析過程可以參考一下https://bbs.kanxue.com/thread-276536.htm
但是這個題要比旺仔拿到的那個要增加些許難度,主要就是增加了類似于CRC校驗的東西還有反調試的一些東西,需要動態的獲取到目標偏移位置的字節值作為運算
后續還有更高級的其它要求,比如過掉反調試,但是我感覺像過反調試這種東西一定要用驅動的,不然隨意的重寫幾個反調試的API就會讓分析變得非常難,當然也可以選擇使用一些別人寫好的插件(但是那樣并不代表你自身的實力),在分析了一些反調試后發現果真重寫了幾個反調試API,隨即停止后續分析,以下是算法的整個還原結果
#include<stdio.h>
#include<Windows.h>int main()
{char True_Key[26];char Name[1024] = "12345678";char v20[28];char v18[28];char v22[28];int j;int i;unsigned int v13 = 0x19820714;int m;int v2;DWORD targetProcessId;printf("請輸入目標進程PID:");scanf_s("%d",&targetProcessId);// 打開目標進程HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, targetProcessId);if (hProcess == NULL){return 1;}// 要讀取的內存地址LPVOID address = (LPVOID)0x401BA9; // 替換成目標進程中要讀取的實際內存地址// 讀取的數據緩沖區BYTE buffer[10000] = { 0 }; // 根據需要調整緩沖區大小// 實際讀取的字節數SIZE_T bytesRead = 0;// 讀取內存if (ReadProcessMemory(hProcess, address, buffer, sizeof(buffer), &bytesRead)){// 在此處處理讀取到的內存數據for (i = 0; i < 2400; v13 ^= *((DWORD*)buffer + i++))v2 = i;}else{// 讀取失敗處理邏輯printf("讀取失敗\n");}// 關閉目標進程句柄CloseHandle(hProcess);memset(v20, 0, 25);memset(v22, 0, 25);memset(v18, 0, 28);memset(True_Key, 0, sizeof(True_Key));v20[0] = '0';v22[0] = 'A';v18[0] = 'a';unsigned __int8 v8;unsigned __int8 v7;unsigned __int8 v6;for (j = 1; j < 26; ++j){v20[j] = v20[j - 1] + 1;v22[j] = v22[j - 1] + 1;v18[j] = v18[j - 1] + 1;}char v25[] = { 0xF7,0xFF,0xFF,0x89,0x8D,0x4C,0xF7,0xFF };char v19[] = { 0x07,0x82,0x19,0xE8,0x1F,0xFE,0xFF,0xFF };int k;for (k = 0; k < 8; ++k){Name[k] ^= k;Name[k] ^= v25[k];Name[k] ^= v19[k];}*(DWORD*)Name ^= v13;*(DWORD*)&Name[4] ^= v13;memset(True_Key, 0, sizeof(True_Key));for (m = 0; m < 8; ++m){v8 = (unsigned __int8)(Name[m] & 0xE0) / 32;v6 = (Name[m] & 0x1C) / 4;v7 = Name[m] & 3;if (m % 3 == 2){True_Key[3 * m] = v20[v7];True_Key[3 * m + 1] = v22[v8 + 8];True_Key[3 * m + 2] = v18[v6 + 16];}if (m % 3 == 1){True_Key[3 * m] = v22[v8 + 16];True_Key[3 * m + 1] = v18[v6 + 8];True_Key[3 * m + 2] = v20[v7];}if (!(m % 3)){True_Key[3 * m] = v22[v6 + 16];True_Key[3 * m + 1] = v18[v7 + 8];True_Key[3 * m + 2] = v20[v8];}}printf("%s\n", True_Key);system("pause");
}