穷举接口-将PE作为DLL载入

来源:互联网 发布:北京通州淘宝运营培训 编辑:程序博客网 时间:2024/06/06 00:54

前言

做了一道CTF的题, 因为不能确定算法,经过调试,弄清接口和参数后,直接穷举爆破了.
将PE当作DLL载入,直接调用接口,还可以在VC中直接进接口,反汇编直接调试.
这招好使.
唯一的缺点 : 因为PE没有重定位表,只有载入时,和PE默认载入地址相同时,才能正常运行。
如果载入时,不是目标PE要求的默认载入地址,可能要退出程序,重新运行重试.
对于临时性的穷举程序,这样也能接受了.
对于穷举类的爆破,在逆向分析后,进行针对性的穷举,效果要好的多,时间是可以预期的,效果好的话几秒钟搞定。
如果不逆向分析,直接在UI上进行蛮力穷举,效果不可预期.

试验记录

// hw.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <windows.h>#include <stdlib.h>#include <stdio.h>#include <math.h>#include <windows.h>DWORD Base;DWORD pfn = 0;// void __declspec(naked) fnCalcRegSn1/*<eax>*/(signed int a1/*<edx>*/, int a2/*<ecx>*/, int a3/*<ebp>*/)// {//// }typedef void (*PFN_fnCalcRegSn1)/*<eax>*/();char ucAryPwdCharSet[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',                          'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',                          'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'                         };int main(int argc, char* argv[]){    // v4 和szBuf必须前2个, pfn1要用    int v4; // ebp@0    CHAR szBuf[0x200] = {'\0'}; // [sp+4h] [bp-204h]@7    int iBuf = 0;    PFN_fnCalcRegSn1 pfn1 = NULL;    int iRc = -2;    DWORD dwProt;    int iLenAryPwdCharSet = sizeof(ucAryPwdCharSet);    int iLoop1 = 0;    int iLoop2 = 0;    int iLoop3 = 0;    int iLoop4 = 0;    int iLoop5 = 0;    int iLoop6 = 0;    int iLoop7 = 0;    // 284 KB (290,816 字节) => 290816 => 0x47000    // CrackMe.exe 默认装载地址为0x0040xxxx    // 00401000 > $  53            push ebx                                 ;  注册码比对    // 程序基地址改为 0x200000    Base = (DWORD)LoadLibraryEx("CrackMe.exe", NULL, DONT_RESOLVE_DLL_REFERENCES);    VirtualProtect((LPVOID)Base, 0x47000, PAGE_EXECUTE_READWRITE, &dwProt);    if (Base == 0x400000) {        // 00401000 > $  53            push ebx                                              ;  注册码比对        pfn = Base + 0x1000;        pfn1 = (PFN_fnCalcRegSn1)pfn;        // 根据调试记录, 前7个字母是此cm的产生数据的原数据        // 穷举前7个字符, 规模不大        for (iLoop1 = 0; iLoop1 < iLenAryPwdCharSet; iLoop1++) {            for (iLoop2 = 0; iLoop2 < iLenAryPwdCharSet; iLoop2++) {                for (iLoop3 = 0; iLoop3 < iLenAryPwdCharSet; iLoop3++) {                    for (iLoop4 = 0; iLoop4 < iLenAryPwdCharSet; iLoop4++) {                        for (iLoop5 = 0; iLoop5 < iLenAryPwdCharSet; iLoop5++) {                            for (iLoop6 = 0; iLoop6 < iLenAryPwdCharSet; iLoop6++) {                                for (iLoop7 = 0; iLoop7 < iLenAryPwdCharSet; iLoop7++) {                                    strcpy(szBuf, "111111111111111111111111111111");                                    szBuf[0] = ucAryPwdCharSet[iLoop1];                                    szBuf[1] = ucAryPwdCharSet[iLoop2];                                    szBuf[2] = ucAryPwdCharSet[iLoop3];                                    szBuf[3] = ucAryPwdCharSet[iLoop4];                                    szBuf[4] = ucAryPwdCharSet[iLoop5];                                    szBuf[5] = ucAryPwdCharSet[iLoop6];                                    szBuf[6] = ucAryPwdCharSet[iLoop7];                                    iBuf = (int)szBuf;                                    __asm {                                        mov edx, 30                                        mov ecx, iBuf                                    };                                    iRc = 0;                                    pfn1();                                    __asm {                                        mov iRc, eax                                    };                                    if (iRc > 0) {                                        ::MessageBox(NULL, szBuf, "找到注册码!", MB_OK);                                        OutputDebugString("找到注册码!\r\n");                                        OutputDebugString(szBuf);                                        OutputDebugString("\r\n");                                    } else {                                        OutputDebugString(".");                                    }                                }                            }                        }                    }                }            }        }    } else {        // 再FreeLibrary, 再LoadLibraryEx没用的, 必须重新启动一次        ::MessageBox(NULL, "错误", "载入目标程序失败, 请重新运行一次", MB_OK);    }    if (0 != Base) {        FreeLibrary((HMODULE)Base);        Base = 0;    }    ::MessageBox(NULL, "END", "穷举结束", MB_OK);    return 0;}
0 0