fly1n 发表于 2017-2-11 06:31

010Editor修改通配符为??教程

最近whyida在论坛上发了一下010Editor最新版的分析和注册机,所以我更换掉了一直使用的WinHex,准备试下010Editor,用起来果然还挺不错的,还能装插件自动识别PE头,但是010Editor里的搜索功能里通配符是用?来代替一个byte,这个和OD里的使用习惯不太一样,OD里都是用??来表示任意byte,所以我用起来总感觉有些别扭,虽然也不是什么大事:\
于是就有了这篇改造010Editor的教程,修改后用??来表示搜索任意byte,如果剩下单数个的?,也会被视作??,比如?FE和??FE都是表示OD里的搜索??FE,???FE和????FE就都表示OD里的????FE
[开始改造]
010Editor在没搜到东西的时候会提示No occurrences of xxx,所以我们搜索ASCII字符串no occurrences,结果如下:
Ultra String Reference Plugin, item 5484
Address=008926FE
Disassembly=PUSH    010Edito.0196E63C
Text String=no occurrences of '
到 008926FE 这里以后一直拉到段首下断,也就是如下位置
00892330   > \55            PUSH    EBP
段首不远处就能看到如下调用
008923A3   .FF15 2C8D6C02 CALL    DWORD PTR DS:[<&Qt5Widgets.QLineEdit::text>]            ;Qt5Widge.QLineEdit::text
这个肯定就是取我们输入的search string了,过这个call以后查看eax会发现确实如此
我们如果要修改使用??来搜索?,一个简单的方法就是把008923A3这行代码返回的QString做一个替换,将??替换为?,因为程序里的原本的搜索功能是用?来搜索一个byte的
右键Qt5Core.dll->详细信息里可以看到使用的Qt版本是5.410,所以我们可以去QT的官网下载一个5.410的环境,写一个replace的函数,编译以后把代码挪过来(或者写成DLL调用也可以),编译好后的replace的函数长这样子:
004019A0/$6A FF         PUSH    -0x1
004019A2|.68 B22D4000   PUSH    QtTest.00402DB2
004019A7|.64:A1 0000000>MOV   EAX, DWORD PTR FS:
004019AD|.50            PUSH    EAX
004019AE|.83EC 08       SUB   ESP, 0x8
004019B1|.56            PUSH    ESI
004019B2|.A1 24704000   MOV   EAX, DWORD PTR DS:
004019B7|.33C4          XOR   EAX, ESP
004019B9|.50            PUSH    EAX
004019BA|.8D4424 10   LEA   EAX, DWORD PTR SS:
004019BE|.64:A3 0000000>MOV   DWORD PTR FS:, EAX
004019C4|.6A FF         PUSH    -0x1
004019C6|.8D4424 10   LEA   EAX, DWORD PTR SS:
004019CA|.68 6C3A4000   PUSH    QtTest.00403A6C                                  ;ASCII "?"
004019CF|.50            PUSH    EAX
004019D0|.FF15 10314000 CALL    DWORD PTR DS:[<&Qt5Core.QString::fromUtf8>]      ;Qt5Core.QString::fromUtf8
004019D6|.8BF0          MOV   ESI, EAX
004019D8|.6A FF         PUSH    -0x1
004019DA|.8D4424 18   LEA   EAX, DWORD PTR SS:
004019DE|.C74424 28 000>MOV   DWORD PTR SS:, 0x0
004019E6|.68 703A4000   PUSH    QtTest.00403A70                                  ;ASCII "??"
004019EB|.50            PUSH    EAX
004019EC|.FF15 10314000 CALL    DWORD PTR DS:[<&Qt5Core.QString::fromUtf8>]      ;Qt5Core.QString::fromUtf8
004019F2|.83C4 18       ADD   ESP, 0x18
004019F5|.8B4C24 20   MOV   ECX, DWORD PTR SS:
004019F9|.6A 01         PUSH    0x1
004019FB|.56            PUSH    ESI
004019FC|.50            PUSH    EAX
004019FD|.C64424 24 01MOV   BYTE PTR SS:, 0x1
00401A02|.FF15 14314000 CALL    DWORD PTR DS:[<&Qt5Core.QString::replace>]       ;Qt5Core.QString::replace
00401A08|.8D4C24 08   LEA   ECX, DWORD PTR SS:
00401A0C|.C64424 18 00MOV   BYTE PTR SS:, 0x0
00401A11|.FF15 18314000 CALL    DWORD PTR DS:[<&Qt5Core.QString::~QString>]      ;Qt5Core.QXmlStreamStringRef::~QXmlStreamStringRef
00401A17|.8D4C24 0C   LEA   ECX, DWORD PTR SS:
00401A1B|.C74424 18 FFF>MOV   DWORD PTR SS:, -0x1
00401A23|.FF15 18314000 CALL    DWORD PTR DS:[<&Qt5Core.QString::~QString>]      ;Qt5Core.QXmlStreamStringRef::~QXmlStreamStringRef
00401A29|.8B4C24 10   MOV   ECX, DWORD PTR SS:
00401A2D|.64:890D 00000>MOV   DWORD PTR FS:, ECX
00401A34|.59            POP   ECX
00401A35|.5E            POP   ESI
00401A36|.83C4 14       ADD   ESP, 0x14
00401A39\.C3            RETN
这个函数我们可以自己改一下,去掉前面的SEH的,然后有些像004019FD,00401A0C,00401A1B这几行的东西好像是用来记录QT函数内部还未销毁的字符串数量的,也可以删掉
然后我们将原来获取LineEdit::text后的三行
008923A9      50            PUSH    EAX
008923AA      8D4D F0       LEA   ECX, DWORD PTR SS:
008923AD      C645 FC 01    MOV   BYTE PTR SS:, 0x1
改为
008923A9   . /E9 52F2C800   JMP   010Edito.01521600
008923AE   |90            NOP
008923AF   |90            NOP
008923B0   |90            NOP
01521600这里就填上我们的replace的代码
01521600   > \50            PUSH    EAX
01521601   .8D4D F0       LEA   ECX, DWORD PTR SS:
01521604   .C645 FC 01    MOV   BYTE PTR SS:, 0x1
01521608   .60            PUSHAD
01521609   .9C            PUSHFD
0152160A   .83EC 08       SUB   ESP, 0x8
0152160D   .6A FF         PUSH    -0x1
0152160F   .8D4424 04   LEA   EAX, DWORD PTR SS:
01521613   .68 80165201   PUSH    010Edito.01521680
01521618   .50            PUSH    EAX
01521619   .FF15 787C6C02 CALL    DWORD PTR DS:[<&Qt5Core.QString:>;Qt5Core.QString::fromUtf8
0152161F   .8BF0          MOV   ESI, EAX
01521621   .6A FF         PUSH    -0x1
01521623   .8D4424 14   LEA   EAX, DWORD PTR SS:
01521627   .68 84165201   PUSH    010Edito.01521684                ;ASCII "??"
0152162C   .50            PUSH    EAX
0152162D   .FF15 787C6C02 CALL    DWORD PTR DS:[<&Qt5Core.QString:>;Qt5Core.QString::fromUtf8
01521633   .6A 01         PUSH    0x1
01521635   .56            PUSH    ESI
01521636   .50            PUSH    EAX
01521637   .8D8C24 800000>LEA   ECX, DWORD PTR SS:
0152163E   .FF15 447A6C02 CALL    DWORD PTR DS:[<&Qt5Core.QString:>;Qt5Core.QString::replace
01521644   .8D4C24 18   LEA   ECX, DWORD PTR SS:
01521648   .FF15 A4746C02 CALL    DWORD PTR DS:[<&Qt5Core.QString:>;Qt5Core.QXmlStreamStringRef::~QXmlStreamStringRef
0152164E   .8D4C24 1C   LEA   ECX, DWORD PTR SS:
01521652   .FF15 A4746C02 CALL    DWORD PTR DS:[<&Qt5Core.QString:>;Qt5Core.QXmlStreamStringRef::~QXmlStreamStringRef
01521658   .83C4 20       ADD   ESP, 0x20
0152165B   .9D            POPFD
0152165C   .61            POPAD
0152165D   .^ E9 4F0D37FF   JMP   010Edito.008923B1
其中01521680和01521684处需要手动填充一下数据如下
015216800000003F?...
0152168400003F3F??..
把修改都保存一下,第一步的改造就完成了,第二步是改掉搜索栏右侧的字符串提示,如下

右侧的?? ?? FE也应该显示为?? FE
我们先给LineEdit::text,也就是65105890下个断,然后我们在010Editor中按Ctrl+F,这个时候程序就需要读取LineEdit里的值从而去显示旁边的数据,所以我们从LineEdit::text里返回,看到如下代码
008952EA   .8D45 E8       LEA   EAX, DWORD PTR SS:
008952ED   .50            PUSH    EAX
008952EE   .FF15 2C8D6C02 CALL    DWORD PTR DS:[<&Qt5Widgets.QLineEdit::text>]            ;Get Original text
008952F4   .8B8B E8000000 MOV   ECX, DWORD PTR DS:
008952FA   .6A 00         PUSH    0x0
008952FC   .68 18576C02   PUSH    010Edito.026C5718
00895301   .56            PUSH    ESI
00895302   .57            PUSH    EDI
00895303   .FF348D 9C316B>PUSH    DWORD PTR DS:
0089530A   .8B4D EC       MOV   ECX, DWORD PTR SS:
0089530D   .50            PUSH    EAX
0089530E   .8D45 F0       LEA   EAX, DWORD PTR SS:
00895311   .C745 FC 00000>MOV   DWORD PTR SS:, 0x0
00895318   .50            PUSH    EAX
00895319   .E8 FBD5B6FF   CALL    010Edito.00402919                                       ;Handle text
0089531E   .8D4D E8       LEA   ECX, DWORD PTR SS:
00895321   .C645 FC 02    MOV   BYTE PTR SS:, 0x2
00895325   .FF15 A4746C02 CALL    DWORD PTR DS:[<&Qt5Core.QString::~QString>]               ;Qt5Core.QXmlStreamStringRef::~QXmlStreamStringRef
0089532B   .8B4B 54       MOV   ECX, DWORD PTR DS:
0089532E   .8D45 F0       LEA   EAX, DWORD PTR SS:
00895331   .50            PUSH    EAX
00895332   .FF15 288D6C02 CALL    DWORD PTR DS:[<&Qt5Widgets.QLineEdit::setText>]         ;Qt5Widge.QLineEdit::setText
我们看到了关键词setText,那008952EE这行取了原文本,00895332这行setText,字符串处理肯定就是00895319这行了
我们跟进去发现是0106F27B这行处理的原文本
0106F27B    E8 AA5C39FF         CALL    010Edito.00404F2A                                    ; !!!
这个函数是在逐个BYTE的读取一个数组,然后产生显示在右边的字符串
这个数组是将你原来查找的字符串换成二进制然后处理问号和星号等特殊符号,例子如下
FE 01 FE
第一个FE表示?,第二个01表示后面有1个非通配符,然后程序就读取后面的FE,由于之前有个01,这个FE不会被当做?,所以FE 01 FE表示的就是搜索?FE,同理01 FE FE就表示搜索FE?,这个数组是在0106F27B CALL    010Edito.00404F2A这行之前的0106F22A这一行被产生的
0106F22A    E8 426639FF         CALL    010Edito.00405871
生成右边的主要部分大致相当于以下代码
i = 0;
do
{
c = a;
if ( c == 0xFF )
{
    *(_WORD *)pNewStr = 0x2A2A;
    pNewStr += 2;
    ++i;
}
else if ( c == 0xFE )
{
    *(_WORD *)pNewStr = 0x3F3F;
    pNewStr += 2;
    ++i;
}
else
{
    ++i;
    ctr = 0;
    if ( c > 0 )
    {
      do
      {
      sprintf(pNewStr, "%02X", a);
      pNewStr += 2;
      if ( ctr < c - 1 )
          *pNewStr++ = 0x20;
      ++ctr;
      ++i;
      }
      while ( ctr < c );
    }
}
if ( i >= a->length )
    break;
*pNewStr++ = 0x20;
}
while ( i < a->length );
我们只要加一个flag记录上一个字符是不是单数个问号就行了,如果当前字符是问号且flag==true,就跳过这次的输出,并且将flag置为false,同时在输出空格的位置判断上一个字符是不是空格,如果是的话就跳过这次的空格输出,修改后的代码如下
<0106D750>

@L00000001:
        PUSH    EBP
        MOV   EBP, ESP
        PUSH    -0x1
        PUSH    0x15168A3
        MOV   EAX, DWORD PTR FS:
        PUSH    EAX
        SUB   ESP, 0x10
        PUSH    EBX
        PUSH    ESI
        PUSH    EDI
        MOV   EAX, DWORD PTR DS:
        XOR   EAX, EBP
        PUSH    EAX
        LEA   EAX, DWORD PTR SS:
        MOV   DWORD PTR FS:, EAX
        MOV   EBX, ECX
        MOV   DWORD PTR SS:, EBX
        LEA   ECX, DWORD PTR SS:
        MOV   DWORD PTR SS:, 0x0
        CALL    DWORD PTR DS:
        CMP   DWORD PTR SS:, 0x0
        MOV   DWORD PTR SS:, 0x1
        JNZ   SHORT @L00000002
        MOV   ESI, DWORD PTR SS:
        PUSH    0x2
        PUSH    DWORD PTR SS:
        PUSH    DWORD PTR SS:
        PUSH    ESI
        CALL    004097A5
        ADD   ESP, 0x10
        LEA   ECX, DWORD PTR SS:
        MOV   DWORD PTR SS:, 0x1
        MOV   BYTE PTR SS:, 0x0
        CALL    DWORD PTR DS:
        MOV   EAX, ESI
        MOV   ECX, DWORD PTR SS:
        MOV   DWORD PTR FS:, ECX
        POP   ECX
        POP   EDI
        POP   ESI
        POP   EBX
        MOV   ESP, EBP
        POP   EBP
        RETN    0x10

@L00000002:
        ;------------------------------------
        MOV   BYTE PTR DS:, 0x0
        ;------------------------------------
        MOV   EAX, DWORD PTR DS:
        LEA   EAX, DWORD PTR DS:
        INC   EAX
        PUSH    EAX
        CALL    013A6CD0
        MOV   ESI, EAX
        MOV   DWORD PTR SS:, EAX
        XOR   EDI, EDI
        ADD   ESP, 0x4
        MOV   BYTE PTR DS:, 0x0
        CMP   DWORD PTR DS:, EDI
        JLE   @L00000010
        MOV   ECX, DWORD PTR SS:

@L00000003:
        MOVZX   EAX, BYTE PTR DS:
        MOV   DWORD PTR SS:, EAX
        CMP   EAX, 0xFF
        JNZ   SHORT @L00000004
        MOV   BYTE PTR DS:, 0x0
        MOV   WORD PTR DS:, 0x2A2A
        ADD   ESI, 0x2
        INC   EDI
        JMP   SHORT @L00000008

@L00000004:
        CMP   EAX, 0xFE
        JNZ   SHORT @L00000005
        ;-----------------------------------
        CMP   BYTE PTR DS:, 0x0
        NOT                BYTE PTR DS:
        JNESHORT @SKIP
        MOV   WORD PTR DS:, 0x3F3F
        ADD   ESI, 0x2

@SKIP:
        ;-----------------------------------
        INC   EDI
        JMP   SHORT @L00000008

@L00000005:
        MOV   BYTE PTR DS:, 0x0
        INC   EDI
        XOR   EBX, EBX
        TEST    EAX, EAX
        JLE   SHORT @L00000008
        DEC   EAX
        MOV   DWORD PTR SS:, EAX

@L00000006:
        MOVZX   EAX, BYTE PTR DS:
        PUSH    EAX
        PUSH    0x1623AEC
        PUSH    ESI
        CALL    DWORD PTR DS:
        ADD   ESP, 0xC
        ADD   ESI, 0x2
        CMP   EBX, DWORD PTR SS:
        JGE   SHORT @L00000007
        MOV   BYTE PTR DS:, 0x20
        INC   ESI

@L00000007:
        MOV   ECX, DWORD PTR SS:
        INC   EBX
        INC   EDI
        CMP   EBX, DWORD PTR SS:
        JL      SHORT @L00000006

@L00000008:
        MOV   EAX, DWORD PTR SS:
        CMP   EDI, DWORD PTR DS:
        JGE   SHORT @L00000009
        ;------------------------------------
        CMP                EDI, 0
        JE                @ADDSPACE
        CMP                BYTE PTR DS:, 0x20
        JE                @DONTADD
@ADDSPACE:
        MOV   BYTE PTR DS:, 0x20
        INC   ESI
@DONTADD:
        ;------------------------------------
        CMP   EDI, DWORD PTR DS:
        JL      @L00000003

@L00000009:
        MOV   EAX, DWORD PTR SS:

@L00000010:
        PUSH    EAX
        LEA   ECX, DWORD PTR SS:
        MOV   BYTE PTR DS:, 0x0
        CALL    DWORD PTR DS:
        PUSH    DWORD PTR SS:
        CALL    013A704C
        MOV   ECX, DWORD PTR SS:
        LEA   EAX, DWORD PTR SS:
        ADD   ESP, 0x4
        PUSH    EAX
        CALL    DWORD PTR DS:
        LEA   ECX, DWORD PTR SS:
        MOV   DWORD PTR SS:, 0x1
        MOV   BYTE PTR SS:, 0x0
        CALL    DWORD PTR DS:
        MOV   EAX, DWORD PTR SS:
        MOV   ECX, DWORD PTR SS:
        MOV   DWORD PTR FS:, ECX
        POP   ECX
        POP   EDI
        POP   ESI
        POP   EBX
        MOV   ESP, EBP
        POP   EBP
        RETN    0x10
现在修改的部分已经都做完了,不过还没完!还需要修正程序的重定位信息,工具我放在附件里了,只有几个位置,手动修复的,就不详细说了
完工以后程序:
链接: http://pan.baidu.com/s/1o7GgQ86 密码: ytyw
错误之处感谢指正!有什么bug也可以告诉我~

冥界3大法王 发表于 2017-2-11 08:49

不错,这个厉害的。

fly1n 发表于 2017-3-1 04:47

青衣惆怅 发表于 2017-2-25 11:13
大婶~文章的意思是不是讲的把程序原来 查询的那个函数替换成自己写的函数。过程是先把自己写好的函数然后编 ...

这个是最完美的方案,你可以完全自己重写搜索的函数从而支持单个16进制位的搜索及?,但是我比较懒,仅仅是在调用内部的搜索函数之前给它加了一个函数,替换搜索字符串,搜索函数还是用的它的。如果直接替换搜索函数还会有个问题,取决于他的搜索函数耦合度低不低,如果他的搜索函数是写成Search(QString &pattern, QString &text)这种,你就很好替换,自己用QT写一个编译以后挪过去就好了,但是如果他的搜索函数写成Search(QString &pattern)这种,然后在函数内再去获取text,比如是调用ui->txtBox->text()获取的,那就不是很好替换了,需要你自己去拼凑

Hmily 发表于 2017-2-11 09:17

学习了思路,先编译代码再挪过来{:1_921:}

yinliming8 发表于 2017-2-11 09:44

学习下,虽然看不懂。

mayl8822 发表于 2017-2-11 10:33

百度盘密码是多少来着

q943959519 发表于 2017-2-11 11:06

好深奥。。

无阻 发表于 2017-2-11 12:43

别的语言软件也可以先写一个子程序代码? 然后直接COPY过来用吗??

fly1n 发表于 2017-2-11 15:36

无阻 发表于 2017-2-11 12:43
别的语言软件也可以先写一个子程序代码? 然后直接COPY过来用吗??

都可以吧,和写一个DLL然后调用其实没有本质的区别吧?

fly1n 发表于 2017-2-11 15:36

mayl8822 发表于 2017-2-11 10:33
百度盘密码是多少来着

你得先开八门,然后再用白眼才能看得到

榻榻米 发表于 2017-2-11 17:01

一般人根本看不懂啊这。。
页: [1] 2 3 4 5 6 7
查看完整版本: 010Editor修改通配符为??教程