吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7712|回复: 17
收起左侧

[原创] 160 个CrackMe之 124 - noos.3 (VB5 p-code)算法分析和5秒爆破算码注册机

  [复制链接]
solly 发表于 2019-4-29 15:25
本帖最后由 solly 于 2019-6-23 22:31 编辑

160 个 CrackMe 之 124 -- noos.3 是一个VB5编写的CrackMe程序,运行时需要 Visual Basic 5.0 运行库支持(MSVBVM50.DLL等),同时这个程序是编译成p-code的程序,需要跟踪p-code中间码,虽然我从QB4.5,VB4到VB6都用过,后面的VB.NET没用过,对Basic语法非常了解(show years old?),但对p-code没怎么了解过,以前也没有跟踪过,所以跟踪这个CM花了不少时间,了解了p-code的跟踪,虽然VB p-code现在用不到了,但我们的目标不是在于用不用这个语言,而是在于理解更多的知识,老知识是新知识的基础,就象现在的虚拟机加壳,是不是与p-code码有点相似???

这个CM的追踪,用到了几个工具,包括 WKTVBDebugger,VBExplorer和OllyICE,三个工具各有各的作用。
1、WKTVBDebugger不是用来调试和跟踪,而是用来查询MSVBVM50.DLL中对p-code的中间码进行解释执行的各个函数。
2、VBExplorer用来反编译CM程序,找到各个控件的执行代码,不过还是p-code代码。(试过其它几种VB反编译器,这个CM用VBExplorer效果完美,其它几个都不行,包括 VB Decompiler Pro都不行)
3、OllyICE则是用来一步一步跟踪调试程序,当然跟踪的都是 MSVBVM50.DLL 中的代码,因为 VB p-code代码都是由MSVBVM50.DLL来执行,没有原生二进制代码。至于为什么用  OllyICE,而不用 WKTVBDebugger,那就是  WKTVBDebugger 是 p-code 代码级跟踪,但一个p-code包括多个微操作,只有 OllyICE跟踪MSVBVM50.DLL才看得到,而 WKTVBDebugger 却不行,特别是一些数据保存,用WKTVBDebugger跟踪,不晓得存到哪里去了,还有那个栈的显示方式也不方便。

另外,为了后期算法效果验证,装了一个win98的虚拟机和一套Visual Basic 5,把p-code代码改编成 basic代码,直接将这个 CM reverse成一个basic源码CM了。

VB p-code 代码中,有下面几个特点:
1、MSVBVM50.DLL 将CPU的寄存器 ESI 是作为p-code指令寄存器使用的,MSVBVM50.DLL内部通过ESI中的地址来读取指令,并解释执行。
2、使用 EBP 寄存器作为变量的地址基址寄存器,所有变量在 p-code 的指令中都是保存为一个相对偏移量,在访问变量前需加上EBP的值,作为其真正的数据地址来读取数据。
3、函数调用的参数、参与计算的变量的值,或者字符串数据的地址,都是通过栈来管理的,数据使用前,均push到栈,指令执行时再pop出来,运算或调用的结果再重新push到栈,这个有点类似CPU的浮点指令的处理方式
4、每个p-code指令执行完成后,接着会通过ESI的指示取出下一条指令到EAX中,再通过一条类似 JMP DWORD PTR[EAX*4+0x741BED94]的指令跳转到该指令的解释程序,对刚取出的指令进行处理,依次类推。。。

VB中的变量,可以不定义类型,默认是一个 Variant 类型,这类种类型对于跟踪来説,也非常麻烦,占用16个字节不説,也不直观,数字还好,字符串还是一个引用地址,比较麻烦。
Variant中VS98的头文件中有定义,如下:
[Asm] 纯文本查看 复制代码
struct  tagVARIANT
    {
    union 
        {
        struct  __tagVARIANT
            {
            VARTYPE vt;
            WORD wReserved1;
            WORD wReserved2;
            WORD wReserved3;
            union 
                {
                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 __RPC_FAR *punkVal;
                IDispatch __RPC_FAR *pdispVal;
                SAFEARRAY __RPC_FAR *parray;
                BYTE __RPC_FAR *pbVal;
                SHORT __RPC_FAR *piVal;
                LONG __RPC_FAR *plVal;
                FLOAT __RPC_FAR *pfltVal;
                DOUBLE __RPC_FAR *pdblVal;
                VARIANT_BOOL __RPC_FAR *pboolVal;
                _VARIANT_BOOL __RPC_FAR *pbool;
                SCODE __RPC_FAR *pscode;
                CY __RPC_FAR *pcyVal;
                DATE __RPC_FAR *pdate;
                BSTR __RPC_FAR *pbstrVal;
                IUnknown __RPC_FAR *__RPC_FAR *ppunkVal;
                IDispatch __RPC_FAR *__RPC_FAR *ppdispVal;
                SAFEARRAY __RPC_FAR *__RPC_FAR *pparray;
                VARIANT __RPC_FAR *pvarVal;
                PVOID byref;
                CHAR cVal;
                USHORT uiVal;
                ULONG ulVal;
                INT intVal;
                UINT uintVal;
                DECIMAL __RPC_FAR *pdecVal;
                CHAR __RPC_FAR *pcVal;
                USHORT __RPC_FAR *puiVal;
                ULONG __RPC_FAR *pulVal;
                INT __RPC_FAR *pintVal;
                UINT __RPC_FAR *puintVal;
                struct  __tagBRECORD
                    {
                    PVOID pvRecord;
                    IRecordInfo __RPC_FAR *pRecInfo;
                    } __VARIANT_NAME_4;
                } __VARIANT_NAME_3;
            } __VARIANT_NAME_2;
        DECIMAL decVal;
        } __VARIANT_NAME_1;
    };

其中的成员 VARTYPE vt; 指明当前 Variable 变量中保存的实际数据类型,有以下取值:
[C] 纯文本查看 复制代码
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        = 0x0fff,
    VT_VECTOR           = 0x1000,
    VT_ARRAY            = 0x2000,
    VT_BYREF            = 0x4000,
    VT_RESERVED         = 0x8000,
    VT_ILLEGAL          = 0xffff,
    VT_ILLEGALMASKED    = 0x0fff,
    VT_TYPEMASK         = 0x0fff
  } ;


更详细的了解可去 https://docs.microsoft.com/en-us ... p/variant-data-type 看看。

现在进入正题。
下面将过程简单讲一下,先运行一下CM,看看界面:
01.jpg
该CM是要求输入一个Unlock码来解锁,将界面上的红灯变成绿灯,同时将上面那个锁的图片由“Activated”变成“Deactivated”。
该CM的算法相对简单,先生成一个数组,并初始化一些计算后的数据,一些固定值,但CM为了增加难度,是动态运算生成的数据。并且还会生成另外一个索引数组,CM居然一个一个的数组元素进行赋值,一共62个元素,进行了62次同样的操作,导到p-code代码好长。不过,所有的算法都是在一个方法内,没有多层次的调用。

要跟踪p-code代码,先要定位解释p-code代码执行的代码在 MSVBVM50.DLL 中的位置,这个就是通过 WKTVBDebugger 来完成的,下图是 WKTVBDebugger 界面(在我win10机器上,要运行loader两次才会弹出这个调试界面):
02.png
先点击“Form Manager (Ctrl+F)”按钮,调出 VB Form资源管理界面,见上图的左边,在最上面的下拉框中选择“Main",下面几个按钮就可以用了,再点击”command“按钮,在弹出的面板中的下拉框中,选择”Command1“,就显示出了VB程序command按钮的相关信息,如下图:
04.png
我们再将上图中的”BPX“按钮按下,这样就可以断下Command1的Click()事件。
再次我们点击WTKVBDebugger主界面中的”Opcodes (Ctrl+O)“按钮,就会弹出一个”Opcodes Control dialog“,这里就是各种p-code指令在MSVBVM50.DLL中解释执行的子例程地址了,如下图所示:
03.png
如 p-code指令LitStr:的p-code码为0x1B,由msvbvm50.dll中地址为0x741BDE59开始的代码来解释执行的。通过这个地址,我们就可以在 OllyICE中下条件断点了,条件就是ESI的值,这个值在哪里找呢,可以在 WKTVBDebugger中找到,也可以通过VBExplorer来找到,用WKTVBDebugger不方便,我是用VBExplorer来找这个值的,如下图:
05.png

在VBExplorer中,很方便就可以定位各个控件的事件处理过程,在VB中叫做Sub(),可以在代码区看到,指令区第一列就是地址,如上图中的":0041EA08",这个值就是条件断点中ESI的值。
VB还可以查看Form中各个控件的参数,如下图,在列表中可以选择各个控件,查看相关参数:
06.jpg
以上是一些基础知识,下面进入 OllyICE 操作,启动OllyICE,并载入noos.3.exe程序:
07.png
载入后,只有两行指令,就是进入MSVBVM50.DLL。右击”转到-->表达式”,进入下图:
08.png
我们在VBExplorer中查到Command1.Click()事件中的第一条指令是“LargeBos”,然后通过 WKTVBDebugger中的Opcodes Control Dialog查得"LargeBos"的解释代码位于MSVBVM50.DLL中地址0x741BD39E处,我们就在OllyICE中输入这个地址,点“确定”,来到了MSVBVM50.DLL的代码空间:
09.png
然后就在这里下断点,就可以断下Command1.Click()事件,不过要设置条件,如下图,下一个条件断点:
10.png
条件就是p-code的ESI指令寄存器的值,这个值就是 VBExplorer中的指令地址值,因此条件是 ESI>= 0x0041EA08,这里不要用==,要用>=,因为p-code执行前会先取指,当执行这个指令时esi一般指向了指令的参数或下一个指令了,如下图:
11.png
下完条件断点后,地址区会显示紫色背景,如下图:
12.png
到这里,就可以进行跟踪执行了,在OllyICE中跟踪执行p-code代码时,要时刻对照VBExplorer中的指令,通过OllyICE中的ESI和VBExplorer中的地址值,就可以确定当前正在执行哪条p-code指令,这样就能大概确定当前代码正在干什么,不然就是在MSVBVM中乱转了。
下面是跟踪本CM下的所有断点,可以参考一下:
13.png
下面説一下,VB的Variant类型变量在内存中的形式,如下图:
14.png
这是一个16字节的Variant变量,保存了字符串"z"。最前面黄色框框中0x0008表示变量保存的是字符串,后面黄色框框中保存的是“z”字符串的地址,表示"z"保存在“0x006116A4"处,如下图:
15.png
如果是数字类变量,则保存的直接就是数字,不是地址了。

以上是一些操作手法説明,下面对VB代码进一步説明,具体的每个p-code代码的跟踪就不説了,那是一个体力活

该CM的算法写在一个子函数中(在VBExplorer中可找到[sub_0041FB38]),Command1.Click()事件会调用这个子函数,下面对函数作简要分析:
[Visual Basic] 纯文本查看 复制代码
:0041F468  F500000000                      LitI4                      ;Push 00000000
:0041F46D  F53D000000                      LitI4                      ;Push 0000003D
:0041F472  0418FF                          FLdRfVar                   ;Push LOCAL_00E8
:0041F475  FE8E0100FFFF1000                Redim                      ;
******Possible String Ref To->"0"
                               |
:0041F47F  3A08FF1100                      LitVarStr                  ;PushVarString ptr_0041DDE0
:0041F484  F500000000                      LitI4                      ;Push 00000000
:0041F489  6C18FF                          ILdRf                      ;Push DWORD [LOCAL_00E8]
:0041F48C  FCB0                            Ary1StVarCopy              ;
******Possible String Ref To->"1"
                               |
:0041F48E  3AF8FE1200                      LitVarStr                  ;PushVarString ptr_0041DDE8
:0041F493  F501000000                      LitI4                      ;Push 00000001
:0041F498  6C18FF                          ILdRf                      ;Push DWORD [LOCAL_00E8]
:0041F49B  FCB0                            Ary1StVarCopy              ;
'
'
'此处省略 n 行 p-code代码,这大段代码(包括前后留下来的部分代码)就是给一个62个元素的数组赋值
'
'
:0041F801  FCB0                            Ary1StVarCopy              ;
******Possible String Ref To->"y"
                               |
:0041F803  3A48FB4D00                      LitVarStr                  ;PushVarString ptr_0041DFA0
:0041F808  F53C000000                      LitI4                      ;Push 0000003C
:0041F80D  6C18FF                          ILdRf                      ;Push DWORD [LOCAL_00E8]
:0041F810  FCB0                            Ary1StVarCopy              ;
******Possible String Ref To->"z"
                               |
:0041F812  3A38FB4E00                      LitVarStr                  ;PushVarString ptr_0041DFA8
:0041F817  F53D000000                      LitI4                      ;Push 0000003D
:0041F81C  6C18FF                          ILdRf                      ;Push DWORD [LOCAL_00E8]
:0041F81F  FCB0                            Ary1StVarCopy              ;
'
'上面代码生成一个含62个元素的数组,每个元素保存一个字符,字符如下,我们用字符串代替:
' Dim charString As String
' charString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
'这个数组就是后面用来进行对照我们输入的unlock码进行查表的
'
:0041F821  0418FF                          FLdRfVar                   ;Push LOCAL_00E8
:0041F824  0428FB                          FLdRfVar                   ;Push LOCAL_04D8
**********Reference To->msvbvm50.rtcArray
                               |
:0041F827  0A4F000800                      ImpAdCallFPR4              ;Call ptr_0040100C; check stack 0008; Push EAX
:0041F82C  0418FF                          FLdRfVar                   ;Push LOCAL_00E8
:0041F82F  5A                              Erase                      ;vbaErase
:0041F830  0428FB                          FLdRfVar                   ;Push LOCAL_04D8
:0041F833  FCF668FF                        FStVar                     ;
******Possible String Ref To->""
                               |
:0041F837  1B0500                          LitStr                     ;Push ptr_0041DD34
:0041F83A  4364FF                          FStStrCopy                 ;[LOCAL_009C]=SysAllocStringByteLen(Pop, [Pop-4]); SysFreeString Pop
'
'以上代码是复制前面生成的数组,并清理临时变量的空间
'我们将这个数组定义为:
'Dim charArray(62) As Variant 'LOCAL_00E8
'
:0041F83D  F518000000                      LitI4                      ;Push 00000018
:0041F842  7154FF                          FStR4                      ;Pop DWORD [LOCAL_00AC]
:0041F845  F51C000000                      LitI4                      ;Push 0000001C
:0041F84A  7158FF                          FStR4                      ;Pop DWORD [LOCAL_00A8]
'
'以上代码生成两个变量并初始化,我们定义如下,并初始化:
'Dim baseA As Long 'LOCAL_00A8
'Dim baseB As Long 'LOCAL_00AC
'baseA = 28 'H1C
'baseB = 24 'H18
' 下面两个是其它变量定义,后面要用到,这里没相应代码,也没有初始化
'Dim i As Long, j As Long
'Dim f As Double
'--------------------------------------------------------------------------
'下面是定义另一个数组,也是62个元素,并且初始化,我们定义如下:
' Dim Dim charArray2(62) As Variant ' LOCAL_00CC
'
'以下代码初始化前10个元素:
:0041F84D  F500000000                      LitI4                      ;Push 00000000
:0041F852  045CFF                          FLdRfVar                   ;Push LOCAL_00A4
:0041F855  F509000000                      LitI4                      ;Push 00000009
:0041F85A  FE6420FB3104                    ForI4                      ;
'上面是一个For循环定义
' for i=0 to 9 step 1
'
:0041F860  6C5CFF                          ILdRf                      ;Push DWORD [LOCAL_00A4]
:0041F863  6C5CFF                          ILdRf                      ;Push DWORD [LOCAL_00A4]
:0041F866  B2                              MulI4                      ;
:0041F867  6C5CFF                          ILdRf                      ;Push DWORD [LOCAL_00A4]
:0041F86A  B2                              MulI4                      ;
:0041F86B  FD6908FF                        CVarI4                     ;
:0041F86F  6C5CFF                          ILdRf                      ;Push DWORD [LOCAL_00A4]
:0041F872  0434FF                          FLdRfVar                   ;Push LOCAL_00CC
:0041F875  52                              Ary1StVar                  ;
:0041F876  6C5CFF                          ILdRf                      ;Push DWORD [LOCAL_00A4]
:0041F879  0434FF                          FLdRfVar                   ;Push LOCAL_00CC
:0041F87C  FC96                            Ary1LdRfVar                ;
:0041F87E  2808FF1700                      LitVarI2                   ;PushVarInteger 0017
:0041F883  FB9428FB                        AddVar                     ;
:0041F887  6C5CFF                          ILdRf                      ;Push DWORD [LOCAL_00A4]
:0041F88A  0434FF                          FLdRfVar                   ;Push LOCAL_00CC
:0041F88D  52                              Ary1StVar                  ;
:0041F88E  3528FB                          FFree1Var                  ;Free LOCAL_04D8
'以上是循环体,生成第二个数组的前10个元素,对应VB代码如下,是不是很简单:
'     charArray2(i) = i * i * i + 23
'
:0041F891  045CFF                          FLdRfVar                   ;Push LOCAL_00A4
:0041F894  6620FBF803                      NextI4                     ;
'循环结束
'Next i
''以下代码初始化中间26个元素:
:0041F899  F50A000000                      LitI4                      ;Push 0000000A
:0041F89E  045CFF                          FLdRfVar                   ;Push LOCAL_00A4
:0041F8A1  F523000000                      LitI4                      ;Push 00000023
:0041F8A6  FE6418FB8E04                    ForI4                      ;
'上面是一个For循环定义
' for i=10 to 35 step 1
'
:0041F8AC  6C58FF                          ILdRf                      ;Push DWORD [LOCAL_00A8]
:0041F8AF  F502000000                      LitI4                      ;Push 00000002
:0041F8B4  B2                              MulI4                      ;
:0041F8B5  7158FF                          FStR4                      ;Pop DWORD [LOCAL_00A8]
:0041F8B8  6C58FF                          ILdRf                      ;Push DWORD [LOCAL_00A8]
******Possible String Ref To->"MTV"
                               |
:0041F8BB  1B5000                          LitStr                     ;Push ptr_0041DFB0
**********Reference To->msvbvm50.rtcAnsiValueBstr
                               |
:0041F8BE  0B51000400                      ImpAdCallI2                ;Call ptr_00401012; check stack 0004; Push EAX
:0041F8C3  E7                              CI4UI1                     ;
:0041F8C4  FB13                            XorI4                      ;
:0041F8C6  EC                              CR8I4                      ;
:0041F8C7  744CFF                          FStFPR8                    ;Fstp#8 [LOCAL_00B4]
:0041F8CA  6F4CFF                          FLdFPR8                    ;Fld#8 [LOCAL_00B4] 
:0041F8CD  F405                            LitI2_Byte                 ;Push 05
:0041F8CF  EB                              CR8I2                      ;
:0041F8D0  AB                              AddR8                      ;
:0041F8D1  744CFF                          FStFPR8                    ;Fstp#8 [LOCAL_00B4]
:0041F8D4  6F4CFF                          FLdFPR8                    ;Fld#8 [LOCAL_00B4] 
:0041F8D7  FD6B08FF                        CVarR8                     ;
:0041F8DB  6C5CFF                          ILdRf                      ;Push DWORD [LOCAL_00A4]
:0041F8DE  0434FF                          FLdRfVar                   ;Push LOCAL_00CC
:0041F8E1  52                              Ary1StVar                  ;
:0041F8E2  6C58FF                          ILdRf                      ;Push DWORD [LOCAL_00A8]
:0041F8E5  F501000000                      LitI4                      ;Push 00000001
:0041F8EA  AA                              AddI4                      ;
:0041F8EB  7158FF                          FStR4                      ;Pop DWORD [LOCAL_00A8]
'以上是循环体,生成第二个数组的中间26个元素,对应VB代码如下:
'    baseA = baseA * 2
'    f = (baseA Xor Asc("MTV")) + 5
'    charArray2(i) = f
'    baseA = baseA + 1
'
:0041F8EE  045CFF                          FLdRfVar                   ;Push LOCAL_00A4
:0041F8F1  6618FB4404                      NextI4                     ;
'循环结束
'Next i
''下面是初始化第二个数组的最后26个元素:
:0041F8F6  F524000000                      LitI4                      ;Push 00000024
:0041F8FB  045CFF                          FLdRfVar                   ;Push LOCAL_00A4
:0041F8FE  F53D000000                      LitI4                      ;Push 0000003D
:0041F903  FE6410FBEB04                    ForI4                      ;
'上面是For循环定义
' For i=36 to 61 step 1
'
:0041F909  6C54FF                          ILdRf                      ;Push DWORD [LOCAL_00AC]
:0041F90C  F502000000                      LitI4                      ;Push 00000002
:0041F911  B2                              MulI4                      ;
:0041F912  7154FF                          FStR4                      ;Pop DWORD [LOCAL_00AC]
:0041F915  6C54FF                          ILdRf                      ;Push DWORD [LOCAL_00AC]
******Possible String Ref To->"TMF"
                               |
:0041F918  1B5200                          LitStr                     ;Push ptr_0041DFBC
**********Reference To->msvbvm50.rtcAnsiValueBstr
                               |
:0041F91B  0B51000400                      ImpAdCallI2                ;Call ptr_00401012; check stack 0004; Push EAX
:0041F920  E7                              CI4UI1                     ;
:0041F921  FB13                            XorI4                      ;
:0041F923  EC                              CR8I4                      ;
:0041F924  744CFF                          FStFPR8                    ;Fstp#8 [LOCAL_00B4]
:0041F927  6F4CFF                          FLdFPR8                    ;Fld#8 [LOCAL_00B4] 
:0041F92A  F43E                            LitI2_Byte                 ;Push 3E
:0041F92C  EB                              CR8I2                      ;
:0041F92D  AB                              AddR8                      ;
:0041F92E  744CFF                          FStFPR8                    ;Fstp#8 [LOCAL_00B4]
:0041F931  6F4CFF                          FLdFPR8                    ;Fld#8 [LOCAL_00B4] 
:0041F934  FD6B08FF                        CVarR8                     ;
:0041F938  6C5CFF                          ILdRf                      ;Push DWORD [LOCAL_00A4]
:0041F93B  0434FF                          FLdRfVar                   ;Push LOCAL_00CC
:0041F93E  52                              Ary1StVar                  ;
:0041F93F  6C54FF                          ILdRf                      ;Push DWORD [LOCAL_00AC]
:0041F942  F501000000                      LitI4                      ;Push 00000001
:0041F947  AA                              AddI4                      ;
:0041F948  7154FF                          FStR4                      ;Pop DWORD [LOCAL_00AC]
'以上是循环体,生成第二个数组的中间26个元素,对应VB代码如下:
'    baseB = baseB * 2
'    f = (baseB Xor Asc("TMF")) + 62
'    charArray2(i) = f
'    baseB = baseB + 1
'
:0041F94B  045CFF                          FLdRfVar                   ;Push LOCAL_00A4
:0041F94E  6610FBA104                      NextI4                     ;
' 循环结束 
'Next i
''初始化结束,下面就是校验unlock码的过程
:0041F953  0408FB                          FLdRfVar                   ;Push LOCAL_04F8
:0041F956  050100                          ImpAdLdRf                  ;Push ptr
:0041F959  240200                          NewIfNullPr                ;[Pop] [SR]
:0041F95C  0F1C03                          VCallAd                    ;Return the control index 09
:0041F95F  190CFB                          FStAdFunc                  ;
:0041F962  080CFB                          FLdPr                      ;[SR]=[LOCAL_04F4]
***********Reference To:[propget]TextBox.Text
                              |
:0041F965  0DA0000600                      VCallHresult               ;Call ptr_0041DD38
'以上代码,是取界面文本框中的 unlock code
' Dim sn As String
' sn = txtCode.Text
'
:0041F96A  6C08FB                          ILdRf                      ;Push DWORD [LOCAL_04F8]
:0041F96D  4A                              FnLenStr                   ;vbaLenBstr
'以上代码计算unlock code 的长度
'Dim snlen As Integer
'Dim snlen2 As Integer
'
'snlen = Len(sn)
'
:0041F96E  F501000000                      LitI4                      ;Push 00000001
:0041F973  AA                              AddI4                      ;
:0041F974  FC0E                            CUI1I4                     ;
:0041F976  FCF062FF                        FStUI1                     ;
:0041F97A  2F08FB                          FFree1Str                  ;SysFreeString [LOCAL_04F8]; [LOCAL_04F8]=0
:0041F97D  1A0CFB                          FFree1Ad                   ;Push [LOCAL_04F4]; Call [[[LOCAL_04F4]]+8]; [[LOCAL_04F4]]=0 
:0041F980  F401                            LitI2_Byte                 ;Push 01, 循环起点 i=1
:0041F982  FC0D                            CUI1I2                     ;
:0041F984  0460FF                          FLdRfVar                   ;Push LOCAL_00A0, 循环变量 i
:0041F987  FCE062FF                        FLdUI1                     ;
:0041F98B  FC14                            CI2UI1                     ;No Operation
:0041F98D  F401                            LitI2_Byte                 ;Push 01
:0041F98F  AD                              SubI2                      ;
:0041F990  FC0D                            CUI1I2                     ;, 循环结束值 = (snlen2-1)
:0041F992  FE6204FB8005                    ForUI1                     ;
'上面生成另一个长度值加上1的变量,作为后面循环的结束值: 
' snlen2 = (snlen + 1)
'同时生成一个循环
' Dim snArray(22) As String
' unlock code 最长为20字符,界面上限定了,最多输入20个字符,因此定义 snArray(22) 用于保存unlock code
' For j=1 to (snlen2-1) step 1
'-----------------------------------------------------------------------
' 下面是一个循环体将unlock code 分解成单个字符并放入数组snArray(22)
:0041F998  0408FB                          FLdRfVar                   ;Push LOCAL_04F8
:0041F99B  050100                          ImpAdLdRf                  ;Push ptr
:0041F99E  240200                          NewIfNullPr                ;[Pop] [SR]
:0041F9A1  0F1C03                          VCallAd                    ;Return the control index 09
:0041F9A4  190CFB                          FStAdFunc                  ;
:0041F9A7  080CFB                          FLdPr                      ;[SR]=[LOCAL_04F4]
***********Reference To:[propget]TextBox.Text
                              |
:0041F9AA  0DA0000600                      VCallHresult               ;Call ptr_0041DD38
:0041F9AF  28F4FA0100                      LitVarI2                   ;PushVarInteger 0001
:0041F9B4  FCE060FF                        FLdUI1                     ;
:0041F9B8  E7                              CI4UI1                     ;
:0041F9B9  3E08FB                          FLdZeroAd                  ;Push DWORD [LOCAL_04F8]; [LOCAL_04F8]=0
:0041F9BC  4628FB                          CVarStr                    ;
:0041F9BF  04E4FA                          FLdRfVar                   ;Push LOCAL_051C
**********Reference To->msvbvm50.rtcMidCharVar
                               |
:0041F9C2  0A53001000                      ImpAdCallFPR4              ;Call ptr_00401018; check stack 0010; Push EAX
:0041F9C7  04E4FA                          FLdRfVar                   ;Push LOCAL_051C
:0041F9CA  FCE060FF                        FLdUI1                     ;
:0041F9CE  E7                              CI4UI1                     ;
:0041F9CF  041CFF                          FLdRfVar                   ;Push LOCAL_00E4
:0041F9D2  52                              Ary1StVar                  ;
:0041F9D3  1A0CFB                          FFree1Ad                   ;Push [LOCAL_04F4]; Call [[[LOCAL_04F4]]+8]; [[LOCAL_04F4]]=0 
:0041F9D6  36060028FBF4FAE4                FFreeVar                   ;Free 0006/2 variants
'以上是循环体,完成以下功能,就是将unlock code 分解成字符存入数组
'  snArray(j) = Mid(sn, j, 1)
'
:0041F9DF  0460FF                          FLdRfVar                   ;Push LOCAL_00A0
:0041F9E2  FE7804FB3005                    NextUI1                    ;
'循环结束
'Next j
'--------------------------------------------------------------------------------------
'下面是对unlock code 数组进行运算校验是否合法,为两层循环,进行校验。
:0041F9E8  F400                            LitI2_Byte                 ;Push 00
:0041F9EA  FBFD                            CStrUI1                    ;vbaStrI2
:0041F9EC  3178FF                          FStStr                     ;SysFreeString [LOCAL_0088]; [LOCAL_0088]=Pop
'始化变量
'Dim s3 As String
's3 = CStr(0)
'Dim f3 As Double
'f3 = 0
'
:0041F9EF  F501000000                      LitI4                      ;Push 00000001
:0041F9F4  0458FF                          FLdRfVar                   ;Push LOCAL_00A8
:0041F9F7  FCE062FF                        FLdUI1                     ;
:0041F9FB  FC14                            CI2UI1                     ;No Operation
:0041F9FD  F401                            LitI2_Byte                 ;Push 01
:0041F9FF  AD                              SubI2                      ;
:0041FA00  E7                              CI4UI1                     ;
:0041FA01  FE64DCFA0A06                    ForI4                      ;
'第一层循环
' For i=1 to (snlen2-1) step 1
' 遍历 unlock code 数组
:0041FA07  F500000000                      LitI4                      ;Push 00000000
:0041FA0C  045CFF                          FLdRfVar                   ;Push LOCAL_00A4
:0041FA0F  F53D000000                      LitI4                      ;Push 0000003D
:0041FA14  FE64D4FA0206                    ForI4                      ;
'第二层循环
' For j=0 to 61 step 1
'遍历那个 0~z的字符串数组,找出与unlock code 中对应的字符的索引值,通过索引值查询第2个62元素数组中保存的相同索引的数据
:0041FA1A  6C58FF                          ILdRf                      ;Push DWORD [LOCAL_00A8]
:0041FA1D  041CFF                          FLdRfVar                   ;Push LOCAL_00E4
:0041FA20  FC96                            Ary1LdRfVar                ;
:0041FA22  045CFF                          FLdRfVar                   ;Push LOCAL_00A4
:0041FA25  FD930340                        CDargRef                   ;
:0041FA29  0468FF                          FLdRfVar                   ;Push LOCAL_0098
:0041FA2C  FEAE28FB0100                    VarIndexLdVar              ;
:0041FA32  FB33                            EqVarBool                  ;
:0041FA34  3528FB                          FFree1Var                  ;Free LOCAL_04D8
:0041FA37  1CFA05                          BranchF                    ;If Pop=0 then ESI=0041FA62
:0041FA3A  6C78FF                          ILdRf                      ;Push DWORD [LOCAL_0088]
:0041FA3D  4608FF                          CVarStr                    ;
:0041FA40  6C5CFF                          ILdRf                      ;Push DWORD [LOCAL_00A4]
:0041FA43  0434FF                          FLdRfVar                   ;Push LOCAL_00CC
:0041FA46  FC96                            Ary1LdRfVar                ;
:0041FA48  FB9428FB                        AddVar                     ;
:0041FA4C  60                              CStrVarTmp                 ;
:0041FA4D  3178FF                          FStStr                     ;SysFreeString [LOCAL_0088]; [LOCAL_0088]=Pop
:0041FA50  3528FB                          FFree1Var                  ;Free LOCAL_04D8
:0041FA53  6C78FF                          ILdRf                      ;Push DWORD [LOCAL_0088]
:0041FA56  FC33                            CR8Str                     ;
:0041FA58  6C58FF                          ILdRf                      ;Push DWORD [LOCAL_00A8]
:0041FA5B  EC                              CR8I4                      ;
:0041FA5C  B3                              MulR8                      ;
:0041FA5D  FC00                            CStrR8                     ;
:0041FA5F  3178FF                          FStStr                     ;SysFreeString [LOCAL_0088]; [LOCAL_0088]=Pop
'循环体,完成以下运算过程:
'        'If snArray(i) = charArray(j) Then     'using array
'        If snArray(i) = Mid(charString, j + 1, 1) Then 'using string
'           f3 = Val(s3) + charArray2(j)
'           s3 = CStr(f3 * i)
'        End If
'
:0041FA62  045CFF                          FLdRfVar                   ;Push LOCAL_00A4
:0041FA65  66D4FAB205                      NextI4                     ;
'内层循环结束
'Next j
':0041FA6A  0458FF                          FLdRfVar                   ;Push LOCAL_00A8
:0041FA6D  66DCFA9F05                      NextI4                     ;
'外层循环结束
'Next i
':0041FA72  6C78FF                          ILdRf                      ;Push DWORD [LOCAL_0088]
:0041FA75  FC33                            CR8Str                     ;
:0041FA77  FA407D1573D18401                LitDate                    ;
:0041FA80  C8                              EqR4                       ;
:0041FA81  1CC806                          BranchF                    ;If Pop=0 then ESI=0041FB30
'以上代码是对运行结果与一个常量进行对比,上面p-code代码显示是 Date类型,反正就是一个长整数"616388714737576#",VB代码如下:
' If Val(s3) != 616388714737576# Then 
'     goto 0041FB30
' End if
'
' 下面校验正确时的处理:
******Possible String Ref To->"Thank you for registering"
                               |
:0041FA84  1B0000                          LitStr                     ;Push ptr_0041DCFC
:0041FA87  5408001000                      FMemStStrCopy              ;
:0041FA8C  2828FB0100                      LitVarI2                   ;PushVarInteger 0001
:0041FA91  F508000000                      LitI4                      ;Push 00000008
:0041FA96  0478FF                          FLdRfVar                   ;Push LOCAL_0088
:0041FA99  4D08FF0840                      CVarRef                    ;
:0041FA9E  04F4FA                          FLdRfVar                   ;Push LOCAL_050C
**********Reference To->msvbvm50.rtcMidCharVar
                               |
:0041FAA1  0A53001000                      ImpAdCallFPR4              ;Call ptr_00401018; check stack 0010; Push EAX
:0041FAA6  04F4FA                          FLdRfVar                   ;Push LOCAL_050C
:0041FAA9  28E4FA0100                      LitVarI2                   ;PushVarInteger 0001
:0041FAAE  F501000000                      LitI4                      ;Push 00000001
:0041FAB3  0478FF                          FLdRfVar                   ;Push LOCAL_0088
:0041FAB6  4DE8FE0840                      CVarRef                    ;
:0041FABB  04C4FA                          FLdRfVar                   ;Push LOCAL_053C
**********Reference To->msvbvm50.rtcMidCharVar
                               |
:0041FABE  0A53001000                      ImpAdCallFPR4              ;Call ptr_00401018; check stack 0010; Push EAX
:0041FAC3  04C4FA                          FLdRfVar                   ;Push LOCAL_053C
:0041FAC6  FB94B4FA                        AddVar                     ;
:0041FACA  FC22                            CI4Var                     ;vbaI4Var
:0041FACC  9908001400                      FMemStI4                   ;Pop DWORD [[STACK_0008]+0008]
:0041FAD1  360A0028FBE4FAF4                FFreeVar                   ;Free 000A/2 variants
:0041FADE  2828FB0100                      LitVarI2                   ;PushVarInteger 0001
:0041FAE3  F50D000000                      LitI4                      ;Push 0000000D
:0041FAE8  0478FF                          FLdRfVar                   ;Push LOCAL_0088
:0041FAEB  4D08FF0840                      CVarRef                    ;
:0041FAF0  04F4FA                          FLdRfVar                   ;Push LOCAL_050C
**********Reference To->msvbvm50.rtcMidCharVar
                               |
:0041FAF3  0A53001000                      ImpAdCallFPR4              ;Call ptr_00401018; check stack 0010; Push EAX
:0041FAF8  04F4FA                          FLdRfVar                   ;Push LOCAL_050C
:0041FAFB  28E4FA0100                      LitVarI2                   ;PushVarInteger 0001
:0041FB00  F505000000                      LitI4                      ;Push 00000005
:0041FB05  0478FF                          FLdRfVar                   ;Push LOCAL_0088
:0041FB08  4DE8FE0840                      CVarRef                    ;
:0041FB0D  04C4FA                          FLdRfVar                   ;Push LOCAL_053C
**********Reference To->msvbvm50.rtcMidCharVar
                               |
:0041FB10  0A53001000                      ImpAdCallFPR4              ;Call ptr_00401018; check stack 0010; Push EAX
:0041FB15  04C4FA                          FLdRfVar                   ;Push LOCAL_053C
:0041FB18  FB94B4FA                        AddVar                     ;
:0041FB1C  FC22                            CI4Var                     ;vbaI4Var
:0041FB1E  9908001800                      FMemStI4                   ;Pop DWORD [[STACK_0008]+0008]
:0041FB23  360A0028FBE4FAF4                FFreeVar                   ;Free 000A/2 variants
'
'上面代码是生成三个变量:
'Dim thankyou As String
'Dim a1 As Integer, a2 As Integer
'   thankyou = "Thank you for registering"
'   a1 = Val(Mid(s3, 8, 1) + Mid(s3, 1, 1)) '16
'   a2 = Val(Mid(s3, 13, 1) + Mid(s3, 5, 1)) '58
'这三个变量,是下面子函数调用的参数。
'其中一个字符串是"Thank you for registering",不过并不会通过对话框提示
'a1, a2 则是计算后的校验码约束:
' 1、计算后的校验码第8位为1
' 2、计算后的校验码第1位为6
' 3、计算后的校验码第13位为5
' 4、计算后的校验码第5位为8
'-----------------------------------------------------------------------------------------------
' 校验失败来到这里
' 调用一个了函数进行界面状态的显示(不管校验正确与否,都会调用下面的子函数)
**********Reference To-> sub_0041F430
                               |
:0041FB30  0A54000000                      ImpAdCallFPR4              ;Call ptr_0041D60C; check stack 0000; Push EAX
:0041FB35  14                              ExitProc                   ;end proc
:0041FB36  0000                            LargeBos                   ;IDE beginning of line with 00 byte codes


上面就是对关键算法的分析,用Visual Basic语法表示如下:

[Asm] 纯文本查看 复制代码
Public Sub SUB_0041FB38(ByRef iFlag%)
Dim str1 As String 'LOCAL_009C
Dim baseA As Long 'LOCAL_00A8
Dim baseB As Long 'LOCAL_00AC
' iFlag -->00A4
Dim charArray(62) As Variant 'LOCAL_00E8
Dim charArray2(62) As Variant ' LOCAL_00CC

Dim charString As String

On Error Resume Next

charString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
'using string replace of array follow:
charArray(0) = "0"
charArray(1) = "1"
charArray(2) = "2"
charArray(3) = "3"
charArray(4) = "4"
charArray(5) = "5"
charArray(6) = "6"
charArray(7) = "7"
charArray(8) = "8"
charArray(9) = "9"
charArray(10) = "A"
charArray(11) = "B"
charArray(12) = "C"
charArray(13) = "D"
charArray(14) = "E"
charArray(15) = "F"
charArray(16) = "G"
charArray(17) = "H"
charArray(18) = "I"
charArray(19) = "J"
charArray(20) = "K"
charArray(21) = "L"
charArray(22) = "M"
charArray(23) = "N"
charArray(24) = "O"
charArray(25) = "P"
charArray(26) = "Q"
charArray(27) = "R"
charArray(28) = "S"
charArray(29) = "T"
charArray(30) = "U"
charArray(31) = "V"
charArray(32) = "W"
charArray(33) = "X"
charArray(34) = "Y"
charArray(35) = "Z"
charArray(36) = "a"
charArray(37) = "b"
charArray(38) = "c"
charArray(39) = "d"
charArray(40) = "e"
charArray(41) = "f"
charArray(42) = "g"
charArray(43) = "h"
charArray(44) = "i"
charArray(45) = "j"
charArray(46) = "k"
charArray(47) = "l"
charArray(48) = "m"
charArray(49) = "n"
charArray(50) = "o"
charArray(51) = "p"
charArray(52) = "q"
charArray(53) = "r"
charArray(54) = "s"
charArray(55) = "t"
charArray(56) = "u"
charArray(57) = "v"
charArray(58) = "w"
charArray(59) = "x"
charArray(60) = "y"
charArray(61) = "z"

baseA = 28 'H1C
baseB = 24 'H18

Dim s1 As String
Dim s2 As String

s1 = "MTV"
s2 = "TMF"

Dim i As Long, j As Long
Dim f As Double

For i = 0 To 9 Step 1
    charArray2(i) = i * i * i + 23
Next i

For i = 10 To 35 Step 1
    baseA = baseA * 2
    f = (baseA Xor Asc(s1)) + 5
    charArray2(i) = f
    baseA = baseA + 1
Next i

For i = 36 To 61 Step 1
    baseB = baseB * 2
    f = (baseB Xor Asc(s2)) + 62
    charArray2(i) = f
    baseB = baseB + 1
Next i

Dim sn As String
sn = txtCode.Text

Dim snArray(22) As String

Dim snlen As Integer
Dim snlen2 As Integer

snlen = Len(sn)
snlen2 = snlen + 1

For j = 1 To (snlen2-1) Step 1
  snArray(j) = Mid(sn, j, 1)
Next j

Dim s3 As String

s3 = CStr(0)

Dim f3 As Double
f3 = 0

For i = 1 To (snlen2-1) Step 1
    For j = 0 To 61 Step 1
        'If snArray(i) = charArray(j) Then     'using array
        If snArray(i) = Mid(charString, j + 1, 1) Then 'using string
           f3 = Val(s3) + charArray2(j)
           s3 = CStr(f3 * i)
        End If
    Next j
Next i

'MsgBox (CStr(s3))

Dim thankyou As String
Dim a1 As Integer, a2 As Integer

If Val(s3) = 616388714737576# Then
    thankyou = "Thank you for registering"

    a1 = Val(Mid(s3, 8, 1) + Mid(s3, 1, 1)) '16
    a2 = Val(Mid(s3, 13, 1) + Mid(s3, 5, 1)) '58

End If

Call sub_41F430(thankyou, a1, a2)

End Sub

算法出来了,通过分析,主要就是查表求和并乘以相应的索引值,也没好办法反向计算,主要查表的索引是通过人为输入的,只有爆破计算unlock code 了,爆破代码如下,大概5秒就可以找到一个unlock code了。
代码是C++的,通过Dev-C++调试通过:
[C++] 纯文本查看 复制代码
#include <iostream>
#include <string.h>
#include <time.h>

unsigned long long base[] = {
        23, 24, 31, 50, 87, 148, 239, 366, 535, 752,     //CrackMe中生成前10个数字,由  (i * i * i + 23) 生成

        122,  68, 176, 392, 984, 1912, 3640, 7352, 14776, 29624, 59320, 118712, 237496, 475064, 950200, 1900472, 
        3801016, 7602104, 15204280, 30408632, 60817336, 121634744, 243269560, 486539192, 973078456, 1946156984,  //// 中间26个数字

        162, 116, 208, 536, 904, 1704, 3176, 6376, 12776, 25576, 51176, 102376, 204776, 409576, 819176, 1638376,
        3276776, 6553576, 13107176, 26214376, 52428776, 104857576, 209715176, 419430376, 838860776, 1677721576    //// 最后26个数字
    };

char sn_str[] = "0123456789ABCDEDGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

//char sn_ok[22] = {'-'};
char sn_ok[] = "----------------------";
int sn_bit[22] = {0};

int testSN(unsigned long long sn, int bit);
int main(int argc, char** argv) {
        
        //unsigned long long sn = 4330972930LL;//616388714737576LL;
        unsigned long long sn_result = 616388714737576LL;
        
        sn_ok[21] = '\0';

        int n=0;
        /// unlock code 最多20个字符,先取得与sn_result能整除几个索引值(也就是长度值) 
        for(int i=20; i>1; i--) {
                if((sn_result % i) == 0) {
                        sn_bit[n++] = i;
                }
        }
        
        /* 
        // n = 11,8,4,2, 最可能的是11,8位两种长度
        11: 56035337703416,
         8: 77048589342197,
         4: 154097178684394,
         2: 308194357368788,
         */ 
        for(int i=0; i<n; i++) {
                printf("n(%d) = %d\n", i, sn_bit[i]);
        }
        
        time_t timep;
        time (&timep);
        printf("\nStart time: %s\n", ctime(&timep));

        if(n>2) {
                n = 2;/// 只测试 11位,8位unlockcode 
        }
        for(int i=0; i<n; i++) {
                sn_ok[sn_bit[i]] = '\0';
                printf("\ntest bits = %d\n", sn_bit[i]);
                int b = testSN(sn_result, sn_bit[i]);
                if(b == 1) {
                        printf("\nUnlock Code: %s\n", sn_ok);
                        break;
                }
        }
        time (&timep);
        printf("\nEnd time: %s", ctime(&timep));

        //system("pause");
        
        return 0;
}

int count = 0;

int testSN(unsigned long long sn, int bit) {
        sn  = sn / bit;
        bit = bit - 1;
        for(int j=61; j>=0; j--) {
                unsigned long long sn1 = sn - base[j];
                if(sn1<0) {
                        continue;
                }
                if((bit==0)) {
                        if((sn1==0)) {
                                sn_ok[bit] = sn_str[j];
                                //printf("sn_ok = %s\n", &sn_ok[bit]);
                                return 1;
                        } else {
                                continue;
                        } 
                }
                if((sn1 % bit) == 0) {
                        sn_ok[bit] = sn_str[j];
                        //printf("bit=%d, sn_part = %s\n", bit+1, sn_ok);
                        int b = testSN(sn1, bit);
                        if(b==1) {
                                //printf("\nSN_OK: %s\n", sn_ok);
                                return 1;
                        } else {
                                sn_ok[bit] = '-';
                        }
                }
        }
        
        return 0;
}

其运行结果如下:
[HTML] 纯文本查看 复制代码
n(0) = 11
n(1) = 8
n(2) = 4
n(3) = 2

Start time: Mon Apr 29 15:21:46 2019


test bits = 11

Unlock Code: LSgbo3t8zzz

End time: Mon Apr 29 15:21:51 2019

--------------------------------
Process exited after 4.65 seconds with return value 0
请按任意键继续. . .


输入生成的 unlock code: LSgbo3t8zzz
看到效果如下图:


16.jpg


完毕!!!!
附件是 noos.3 crackme 的VB源码。

noos3_vbsrc.zip

163.22 KB, 下载次数: 18, 下载积分: 吾爱币 -1 CB

vb 源码

免费评分

参与人数 6吾爱币 +9 热心值 +5 收起 理由
hh_z_l + 1 谢谢@Thanks!
pk8900 + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
笙若 + 1 + 1 谢谢@Thanks!
无的世界零 + 1 + 1 用心讨论,共获提升!
鬼手56 + 1 + 1 &amp;lt;font style=&amp;quot;vertical-align: inherit;&amp;quot;&amp;gt;&amp;lt;font style=
兔子我是胡萝卜 + 2 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| solly 发表于 2019-4-29 15:59
本帖最后由 solly 于 2019-4-29 16:01 编辑
鬼手56 发表于 2019-4-29 15:37
请教一下 WKTVBDebugger不是只支持Windows 2000和NT吗?为什么你的W10可以用

不清楚,我直接可以用,就是要启动两次才可以(第一次闪退,第二次后就可以了)。我的是 Win10 x64 1809 版本。还就就是快捷键不可用,需要鼠标点,这个不方便,代码区也不能上下走,只能看它显示的代码。
 楼主| solly 发表于 2019-4-29 16:51
鬼手56 发表于 2019-4-29 16:03
能否分享下你用的WKTVBDebugger 最近也在调P-Code,奈何一直找不到能用的WKTVBDebugger

是在 pediy.com下载的,可能是我把VB程序需要的相关库文件,包括 MSVBVM50.DLL,以及OCX和其它DLL 都放到应用程序目录,没有放到 windows 的 SysOnWOW64目录。
鬼手56 发表于 2019-4-29 15:37
请教一下 WKTVBDebugger不是只支持Windows 2000和NT吗?为什么你的W10可以用
鬼手56 发表于 2019-4-29 16:03
能否分享下你用的WKTVBDebugger 最近也在调P-Code,奈何一直找不到能用的WKTVBDebugger
无的世界零 发表于 2019-4-29 16:30
写的很详细,谢谢分享
学士天下 发表于 2019-4-29 16:59
学习学习,谢谢楼主的分享,谢谢啦!!!
FENGMUTIAN 发表于 2019-4-29 17:22
前来学习
独狼 发表于 2019-4-29 20:41
哈哈哈哈哈
 楼主| solly 发表于 2019-4-29 20:58

什么情况???
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-25 12:56

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表