文章的思路很简单, /一般的smc技术都是程序在运行的时候对自己的代码进行解密 也就是说解密算法可以在原程序找到. 然后我就想不想把解密算法放到一个程序里面.
简单的说, 有三个程序A, B, C, C是待保护的程序
A对C的关键代码进行加密
B对C坐内存补丁, 然后运行C
下面简单的说下代码实现吧
代码:
//C部分 //这里设置一些标志,方便A对C进行加密 _asm { // int 3 mov eax, 0xAAAAAAAA lea eax, EncryptAddrStart lea eax, EncryptAddrEnd } EncryptAddrStart: MessageBox(GetActiveWindow(), TEXT("hello smc"), TEXT("It's just a test"), MB_OK); EncryptAddrEnd:: //A部分 //寻找加密标志, 返回偏移 encryptoffset = SearchEncryptFlags(lpBaseImage, encryptFlags, imagesize); //找到以后就将关键数据保存 encryptoffset += 6; memcpy(&EncryptAddrStart, (void *)encryptoffset, sizeof(DWORD)); encryptoffset += 6; memcpy(&EncryptAddrEnd, (void *)encryptoffset, sizeof(DWORD)); //加密算法 //这里只做简单的演示,所以采用简单的异或算法 VOID EncryptCode(DWORD EncryptAddr, DWORD EncryptSize, DWORD key) { for (int i = 0; i < (int)EncryptSize; i++) { _asm { mov eax, EncryptAddr mov al, BYTE PTR ds : [eax] mov ebx, key xor al, bl mov esi, EncryptAddr mov BYTE ptr ds : [esi], al } EncryptAddr += 1; } } //这里将一些关键数据写回,方便B对C进行解密 SetFilePointer(hfile, 0, 0, FILE_END); EncryptAddrStart = EncryptAddrStart + (DWORD)imagebase - (DWORD)lpBaseImage; // EncryptAddrEnd = EncryptAddrEnd + (DWORD)imagebase - (DWORD)lpBaseImage; WriteFile(hfile, &EncryptAddrStart, sizeof(DWORD), &bRtn, NULL); WriteFile(hfile, &EncryptAddrEnd, sizeof(DWORD), &bRtn, NULL); //下面是B对C进行解密部分 //首先获取一些关键信息 hfile = CreateFile(szExeFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,\ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == hfile) { ShowErrorInformation(); return FALSE; } SetFilePointer(hfile, -8, NULL, FILE_END); ReadFile(hfile, &DecryptAddrStart, sizeof(DWORD), &bRtn, NULL); ReadFile(hfile, &DecryptAddrEnd, sizeof(DWORD), &bRtn, NULL); //然后创建进程 CreateProcess(szExeFileName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); //对其进行解密 DeCryptCodeFun(pi.hProcess, (void *)DecryptAddrStart, DecryptSize, key); ResumeThread(pi.hThread); //下面是解密函数 resultcheck = ReadProcessMemory(decryptprocess, addrstart, lpDecryptBuffer, decryptsize, &bRtn); if ((FALSE == resultcheck) || (bRtn != decryptsize)) { ShowErrorInformation(); VirtualFree(lpDecryptBuffer, decryptsize, MEM_DECOMMIT); lpDecryptBuffer = NULL; return FALSE; } lpOffset = (DWORD) lpDecryptBuffer; for (int i = 0; i < (int)decryptsize; i=i+1) { _asm { mov eax, lpOffset mov al, BYTE PTR ds : [eax] mov ebx, key xor al, bl mov esi, lpOffset mov BYTE ptr ds : [esi], al } lpOffset = lpOffset + 1; } resultcheck = WriteProcessMemory(decryptprocess, addrstart, lpDecryptBuffer, decryptsize, &bRtn); if ((NULL == resultcheck) || (bRtn != decryptsize)) { ShowErrorInformation(); VirtualFree(lpDecryptBuffer, decryptsize,MEM_DECOMMIT); lpDecryptBuffer = NULL; return FALSE; }