記逆向小白的第一次vbsedit 9爆破及內存補丁制作過程
作為一個搞破解、逆向的小白,第一發(fā)文,請各位大神多指教。
近期需要批量處理一些word和excel文檔,開始一直用word的宏,但是發(fā)給同事用的時候同事老是不會啊。后來就想寫一些VBS的腳本,讓他們直接雙擊運行就好了??墒菍慥BS腳本也需要調試的呀,沒有合適的工具很惱火的。于是上網(wǎng)找到了VBSEdit這么個工具,可是非注冊版每次調試都會彈出一個提示框,等好多秒,找破解版要么版本太老,要么就是夾帶私貨的。于是就想自己動手試一下好了。
下載了x64dbg,啟動,打開vbsedit.exe。點擊Start Debugging 的按鈕,彈出了注冊對話框。
有點懵。不知從何入手。于是就各種搜啊搜啊,最后決定從找對話框開始,搜索跨模塊調用,輸入“dialog”,出現(xiàn)了五個相關的調用:
于是在第一項處下斷點,重新跟到這里后發(fā)現(xiàn)是從1401087B4這一行運行來的,于是在這一行下斷點。
再次跟進來,停下后在右下角的棧區(qū)會看到對這個的調用來自vbsedit.00000000140107C8E,再轉到這個調用點。
然后在從這個調用點往后追溯,就這樣追溯幾次調用后就會找到一個貌似調用注冊對話的地方:
就這個Call <vbsedit.#所有對話框>調用(當然后面的注釋都是我跟的時候自己加的),先試試NOP掉它。
再次運行,注冊對話框不彈了。再試了試其他功能,一切正常。成功!
同樣的方法,可以把單步調試等彈注冊對話框的地方都找到,同樣nop掉。啟動的注冊對話框有一個JNE的判斷,改成JE就好了。
然后就是修補文件,另存了exe。再次運行打了補丁的文件,結果一閃而過,程序運行不了啦。
原來這程序有自校驗,一個字節(jié)都不能改,改了就不能正常運行。要么是沒法正常退出,要么是沒有語法高亮,總之各種不正常。
怎么辦呢?繼續(xù)破自校驗? 算了,對我這個小白來說這個難度有點太大了。
考慮到用x64dbg打開直接在內存修改后可以正常運行,應該說找的爆破位置還是對的,所以如果打個內存補丁應該是可行的。
內存補丁怎么弄呢?沒整過耶,于是又是搜啊搜啊,找到了用Dll劫持注入打補丁的方法。
試了試常用的version.dll,發(fā)現(xiàn)這個dll是可以利用的。接下來就是需要自己寫一個version.dll用來劫持并打內存補丁啦。
祭出了AheadLib這個工具,選擇簡單的直接轉發(fā)函數(shù),生成了version.cpp。
然后在入口函數(shù)里加上自己打補丁的代碼就好了,代碼如下:(小白水平,勿噴)
#include <Windows.h> #include <stdio.h> // 導出函數(shù) #pragma comment(linker, "/EXPORT:GetFileVersionInfoA=c:\\windows\\system32\\version.dll.GetFileVersionInfoA,@1") #pragma comment(linker, "/EXPORT:GetFileVersionInfoByHandle=c:\\windows\\system32\\version.dll.GetFileVersionInfoByHandle,@2") #pragma comment(linker, "/EXPORT:GetFileVersionInfoExA=c:\\windows\\system32\\version.dll.GetFileVersionInfoExA,@3") #pragma comment(linker, "/EXPORT:GetFileVersionInfoExW=c:\\windows\\system32\\version.dll.GetFileVersionInfoExW,@4") #pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeA=c:\\windows\\system32\\version.dll.GetFileVersionInfoSizeA,@5") #pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeExA=c:\\windows\\system32\\version.dll.GetFileVersionInfoSizeExA,@6") #pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeExW=c:\\windows\\system32\\version.dll.GetFileVersionInfoSizeExW,@7") #pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeW=c:\\windows\\system32\\version.dll.GetFileVersionInfoSizeW,@8") #pragma comment(linker, "/EXPORT:GetFileVersionInfoW=c:\\windows\\system32\\version.dll.GetFileVersionInfoW,@9") #pragma comment(linker, "/EXPORT:VerFindFileA=c:\\windows\\system32\\version.dll.VerFindFileA,@10") #pragma comment(linker, "/EXPORT:VerFindFileW=c:\\windows\\system32\\version.dll.VerFindFileW,@11") #pragma comment(linker, "/EXPORT:VerInstallFileA=c:\\windows\\system32\\version.dll.VerInstallFileA,@12") #pragma comment(linker, "/EXPORT:VerInstallFileW=c:\\windows\\system32\\version.dll.VerInstallFileW,@13") #pragma comment(linker, "/EXPORT:VerLanguageNameA=c:\\windows\\system32\\version.dll.VerLanguageNameA,@14") #pragma comment(linker, "/EXPORT:VerLanguageNameW=c:\\windows\\system32\\version.dll.VerLanguageNameW,@15") #pragma comment(linker, "/EXPORT:VerQueryValueA=c:\\windows\\system32\\version.dll.VerQueryValueA,@16") #pragma comment(linker, "/EXPORT:VerQueryValueW=c:\\windows\\system32\\version.dll.VerQueryValueW,@17") //宏 Debug("format string",arg1,arg2,...) //用于Debug調試信息輸出,用法同 printf #ifdef _DEBUG #define Debug(...) DllPrintf(__VA_ARGS__) #else #define Debug(...) #endif int DllPrintf(char *fmt,...) { //dll調試時打開控制臺窗口顯示調試信息 //用法同printf va_list argptr; va_start(argptr,fmt); char buffer[512] ={0}; int cnt = vsprintf_s(buffer,fmt,argptr); va_end(argptr); static HANDLE ghConsole = INVALID_HANDLE_VALUE; if(INVALID_HANDLE_VALUE == ghConsole) { AllocConsole(); ghConsole = GetStdHandle(STD_OUTPUT_HANDLE); } DWORD dw; WriteConsole(ghConsole ,buffer,(DWORD)strlen(buffer),&dw,NULL); return cnt; } void Patch(void) { DWORD dwProcessId; dwProcessId = GetCurrentProcessId(); HANDLE hProcess; hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,dwProcessId); if(hProcess == 0){ Debug("open process error \n"); }else { Debug("the hProcess is : %x\n",(INT)hProcess); } LPVOID lpAddressStart,lpAddressDebug,lpAddressDebugStep; lpAddressStart=(LPVOID)0x000000014009147F;//啟動注冊框的爆破地址 lpAddressDebug=(LPVOID)0x00000001400E3ED7;//debug對話框的爆破地址 lpAddressDebugStep=(LPVOID)0x00000001400DA343;//debug step over對話框的爆破地址 char je=0x74;//je指令 SIZE_T dwNumberOfBytesRead; dwNumberOfBytesRead=0; if(WriteProcessMemory(hProcess,lpAddressStart,&je,sizeof(je),&dwNumberOfBytesRead)) { Debug("%d byte writed,start dialog patch ok!\n ",dwNumberOfBytesRead); }else { Debug("read error:%d \n", GetLastError()); } unsigned char temp[5]={0x90,0x90,0x90,0x90,0x90}; if(WriteProcessMemory(hProcess,lpAddressDebug,&temp,sizeof(temp),&dwNumberOfBytesRead)) { Debug("%d byte writed,debug dialog patch ok!",dwNumberOfBytesRead); }else { Debug("read error:%d \n", GetLastError()); } if(WriteProcessMemory(hProcess,lpAddressDebugStep,&temp,sizeof(temp),&dwNumberOfBytesRead)) { Debug("%d byte writed,debug step over dialog patch ok!",dwNumberOfBytesRead); }else { Debug("read error:%d \n", GetLastError()); } CloseHandle(hProcess); } // 入口函數(shù) BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved) { if (dwReason == DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(hModule); Patch(); } else if (dwReason == DLL_PROCESS_DETACH) { } return TRUE; }
代碼很簡單,有個地方我犯過錯誤,這里記錄一下:
導出函數(shù)的#pragma comment(linker, "/EXPORT:GetFileVersionInfoA=c:\\windows\\system32\\version.dll.GetFileVersionInfoA,@1") 其中 c:\\windows\\system32\\version.dll這個地方,這是用于64位程序的,所以是這個路徑。也可以寫成改名后的dll文件名,比如你把原version.dll文件改成了oldversion.dll,那么就寫成#pragma comment(linker, "/EXPORT:GetFileVersionInfoA=oldversion.dll.GetFileVersionInfoA,@1") 就可以了。不過這樣你需要把oldversion.dll 同樣拷貝到vbsedit.exe的同目錄。如果是我的寫法就只需要把生成的version.dll拷貝到vbsedit.exe程序目錄就行了。
另外dll在控制臺輸出調試信息的方法我也是找了好久,開始一直用MessageBox,很痛苦的。
爆破地址只能適用于vbsedit 9.1226版本。
生成的version.dll拷貝到VBSEdit.exe的同目錄即可。
再次運行,這次沒有了注冊提示框。打開幾個vbs文件,試了試編輯、調試等功能,測試一切正常,成功!
總結:破解逆向好像也沒那么難,呵呵! 我也行 ^_^
到此這篇關于記逆向小白的第一次vbsedit 9爆破及內存補丁制作的文章就介紹到這了,更多相關vbsedit 9爆破及內存補丁內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++使用opencv調用級聯(lián)分類器來識別目標物體的詳細流程
所謂級聯(lián)分類器其實就是把分類器按照一定的順序聯(lián)合到一起,下面這篇文章主要給大家介紹了關于C++使用opencv調用級聯(lián)分類器來識別目標物體的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-05-05