首页
社区
课程
招聘
[旧帖] [求助]用OD跟踪VB软件的困惑 0.00雪花
发表于: 2007-3-1 14:52 5531

[旧帖] [求助]用OD跟踪VB软件的困惑 0.00雪花

hud 活跃值
2
2007-3-1 14:52
5531
问的问题对于高手也许很简单,可是经常困扰我,高手们见笑了。

用OD调试VB程序,在比较字符串时,如果字符串包含多个字符,那么我们可以在OD提示或者寄存器中看到字符串,

-------------------------------------------------------------

但是如果是单个字符的比较,就没有提示,甚至连单个字符的ASCII码也不知放在什么地方。

-------------------------------------------------------------

Option Explicit

Private Sub Command1_Click()
Dim s As String
Dim i As Integer

    s = Text1  '调试时输入"abcde"
    If Len(s) > 0 Then
        If Mid(s, 1, 1) = "A" Then
            MsgBox "OK"
        End If
        
    End If

End Sub


新建一个VB程序,放个TextBox和命令按钮,照上面这一段小程序编译:

00401C40   test eax,eax                            ;  判断Textbox中是否是0
00401C42   jle Test.00401D1C                       ;  是0则退出了程序
00401C48   lea ecx,dword ptr ss:[ebp-1C]           ;  如果不为空到这里,ecx堆栈中为输入的字符串"abcde"
00401C4B   lea edx,dword ptr ss:[ebp-34]
00401C4E   mov dword ptr ss:[ebp-6C],ecx
00401C51   push edx
00401C52   lea eax,dword ptr ss:[ebp-74]
00401C55   push 1
00401C57   lea ecx,dword ptr ss:[ebp-44]
00401C5A   push eax
00401C5B   push ecx
00401C5C   mov dword ptr ss:[ebp-2C],1
00401C63   mov dword ptr ss:[ebp-34],2
00401C6A   mov dword ptr ss:[ebp-74],4008          ;  下面调用 Mid(s, 1, 1)
00401C71   call dword ptr ds:[<&MSVBVM60.#632>]    ;  MSVBVM60.rtcMidCharVar
00401C77   lea edx,dword ptr ss:[ebp-44]           ;  找不到返回的结果'a'(61)在那里
00401C7A   lea eax,dword ptr ss:[ebp-94]
00401C80   push edx
00401C81   push eax
00401C82   mov dword ptr ss:[ebp-8C],Test.004017A8
00401C8C   mov dword ptr ss:[ebp-94],8008          ;  下面要比较,可是找不到相比较的'A'值在那里。
00401C96   call dword ptr ds:[<&MSVBVM60.__vbaVarT>;  MSVBVM60.__vbaVarTstEq
00401C9C   mov ebx,dword ptr ds:[<&MSVBVM60.__vbaF>;  MSVBVM60.__vbaFreeVarList
00401CA2   lea ecx,dword ptr ss:[ebp-44]
00401CA5   lea edx,dword ptr ss:[ebp-34]
00401CA8   push ecx
00401CA9   push edx
00401CAA   push 2
00401CAC   mov esi,eax
00401CAE   call ebx                                ;  <&MSVBVM60.__vbaFreeVarList>
00401CB0   add esp,0C
00401CB3   cmp si,di                               ;  不相等则比较的2个值相等
00401CB6   je short Test.00401D1C
00401CB8   mov ecx,80020004                        ;  比较的2个字符相等到这里

上面这一段要做什么我们清清楚楚,可是问题是:
1. Mid(s, 1, 1)取到的字符放在内存或者堆栈的什么地方?
2. 做这对比的字符'A'又在那里?

请朋友们指点。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 101
活跃值: (12)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
2
首先, vb中如果不显示的定义数据类型, 并且没有加
Option Explicit的话, 那么定义的变量为variant.
variant的结构的前2个字节描述了类型, 后面有3个word的保留.
接着为值.

先说下rtcMidCharVar这个函数.
这个函数有4个参数, 第一个参数是一个variant的指针,
也就是函数的返回值,

第二个参数是同样是一个variant,
但是你前面得到的是一个bstr, 那么需要转换成variant,
看到mov dword ptr ss:[ebp-74],4008
这句话吗, 这其实就是构造一个variant, 类型为4008(bstr引用)

第3个参数为一个位置, 是一个dword值.

第4个参数又是一个variant, 类型为2(word)
mov dword ptr ss:[ebp-34],2

于是, 你的结果返回到第一个参数里面,
我这里是
0012F48C  08 00 00 00 86 4B 47 73 D4 90 15 00 AC F4 12 00  
可以看到, 类型8(b_str), 值为1590d4,
d一下1590d4可以看到
001590D4  41 00 00 00 A...
就是存到这里,
顺便简单说下b_str, b_str是有长度的, 长度保存在字符串的
开头的4个字节里面, 即
001590D0  02 00 00 00 41 00 00 00   

.__vbaVarTstEq:

同样, _vbaVarTstEq判断2个variant, 如果"相等",
则返回-1(vb中boolean类型,用-1表示true,用0表示false),
通过eax返回,  后面的
cmp si,di                              
其实你可以理解成, 因为di始终为0, 为了提速, 所以用di积存器
cmp eax, 0

如果eax为0为false的时候, 则跑了00401D1C
否则, 表示__vbaVarTstEq结果为真, 执行

00401CB8   mov ecx,80020004

开始的代码
2007-3-1 15:34
0
雪    币: 101
活跃值: (12)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
3
补充一下variant结构, 和vartype enum

enum VARENUM
    {        VT_EMPTY        = 0,
        VT_NULL        = 1,
        VT_I2        = 2,
        VT_I4        = 3,
        VT_R4        = 4,
        VT_R8        = 5,
        VT_CY        = 6,
        VT_DATE        = 7,
        VT_BSTR        = 8,
        VT_DISPATCH        = 9,
        VT_ERROR        = 10,
        VT_BOOL        = 11,
        VT_VARIANT        = 12,
        VT_UNKNOWN        = 13,
        VT_DECIMAL        = 14,
        VT_I1        = 16,
        VT_UI1        = 17,
        VT_UI2        = 18,
        VT_UI4        = 19,
        VT_I8        = 20,
        VT_UI8        = 21,
        VT_INT        = 22,
        VT_UINT        = 23,
        VT_VOID        = 24,
        VT_HRESULT        = 25,
        VT_PTR        = 26,
        VT_SAFEARRAY        = 27,
        VT_CARRAY        = 28,
        VT_USERDEFINED        = 29,
        VT_LPSTR        = 30,
        VT_LPWSTR        = 31,
        VT_RECORD        = 36,
        VT_INT_PTR        = 37,
        VT_UINT_PTR        = 38,
        VT_FILETIME        = 64,
        VT_BLOB        = 65,
        VT_STREAM        = 66,
        VT_STORAGE        = 67,
        VT_STREAMED_OBJECT        = 68,
        VT_STORED_OBJECT        = 69,
        VT_BLOB_OBJECT        = 70,
        VT_CF        = 71,
        VT_CLSID        = 72,
        VT_VERSIONED_STREAM        = 73,
        VT_BSTR_BLOB        = 0xfff,
        VT_VECTOR        = 0x1000,
        VT_ARRAY        = 0x2000,
        VT_BYREF        = 0x4000,
        VT_RESERVED        = 0x8000,
        VT_ILLEGAL        = 0xffff,
        VT_ILLEGALMASKED        = 0xfff,
        VT_TYPEMASK        = 0xfff
    } ;

struct tagVARIANT
    {
    union
        {
        struct __tagVARIANT
            {
            VARTYPE vt;
            WORD wReserved1;
            WORD wReserved2;
            WORD wReserved3;
            union
                {
                LONGLONG llVal;
                LONG lVal;
                BYTE bVal;
                SHORT iVal;
                FLOAT fltVal;
                DOUBLE dblVal;
                VARIANT_BOOL boolVal;
                _VARIANT_BOOL bool;
                SCODE scode;
                CY cyVal;
                DATE date;
                BSTR bstrVal;
                IUnknown *punkVal;
                IDispatch *pdispVal;
                SAFEARRAY *parray;
                BYTE *pbVal;
                SHORT *piVal;
                LONG *plVal;
                LONGLONG *pllVal;
                FLOAT *pfltVal;
                DOUBLE *pdblVal;
                VARIANT_BOOL *pboolVal;
                _VARIANT_BOOL *pbool;
                SCODE *pscode;
                CY *pcyVal;
                DATE *pdate;
                BSTR *pbstrVal;
                IUnknown **ppunkVal;
                IDispatch **ppdispVal;
                SAFEARRAY **pparray;
                VARIANT *pvarVal;
                PVOID byref;
                CHAR cVal;
                USHORT uiVal;
                ULONG ulVal;
                ULONGLONG ullVal;
                INT intVal;
                UINT uintVal;
                DECIMAL *pdecVal;
                CHAR *pcVal;
                USHORT *puiVal;
                ULONG *pulVal;
                ULONGLONG *pullVal;
                INT *pintVal;
                UINT *puintVal;
                struct __tagBRECORD
                    {
                    PVOID pvRecord;
                    IRecordInfo *pRecInfo;
                    }         __VARIANT_NAME_4;
                }         __VARIANT_NAME_3;
            }         __VARIANT_NAME_2;
        DECIMAL decVal;
        }         __VARIANT_NAME_1;
    } ;
2007-3-1 15:34
0
雪    币: 221
活跃值: (161)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
jjnet:

非常感谢!现在明白了。

上面问题是自己写了一段来跟踪,虽然做什么清清楚楚,但怎么做的之前不明白,如果是跟踪别人的软件,那就两眼一抹黑了。现在疑问解决了,相信以后会对我跟踪VB程序很有用的,再次感谢!
2007-3-2 10:28
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
向高手学习,天天向上:)
2007-3-2 10:53
0
游客
登录 | 注册 方可回帖
返回
//