0xAA55 发表于 2020-7-4 16:42:23

【VB】VB6+ASM实现MD5计算

和上次写的VB6实现SHA1一样,因为我受不了各种无法移位、各种整数乘除法代替移位还不得不使用有符号整数乘除法的操作,我选择直接写汇编,然后以类似于shellcode的方式调用。

Option Explicit

Type MD5Reg_t
    A As Long
    B As Long
    C As Long
    D As Long
End Type

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (Destination As Any, ByVal numBytes As Long)
Private Declare Function CallProcPtr Lib "user32" Alias "CallWindowProcA" (FuncPtr As Any, Arg1 As Any, ByVal Arg2 As Long, ByVal Arg3 As Long, ByVal Arg4 As Long) As Long

Private Const m_MD5_DigestChunkCode As String = "" & _
"83EC1056578B74241C8D7C2408B904000000F3A58B7424208B44240C2344241089C28B44240CF7D02344241409D00344240803060578A46AD7C1C0070344240C894424088B4424082344240C89C28B442408F7D02344241009D0034424140346040556B7C7E8C1C00C03442408894424148B4424142344240889C28B442414F7D02344240C09D00344241003460805DB702024C1C01103442414894424108B4424102344241489C28B442410F7D02344240809D00344240C03460C05EECEBDC1C1C016034424108944240C8B44240C2344241089C28B44240CF7D02344241409D00344240803461005AF0F7CF5C1C0070344240C894424088B4424082344240C89C28B442408F7D02344241009D003442414034614052AC68747C1C00C03442408894424148B4424142344240889C28B442414F7D02344240C09D00344241003461805134630A8C1C01103442414894424108B4424102344241489C28B442410F7D02344240809D00344240C03461C05019546FDC1C016034424108944240C8B44240C2344241089C28B44240CF7D02344241409D00344240803462005D8988069C1C0070344240C894424088B4424082344240C89C28B442408F7D02344241009D00344241403462405AFF7448BC1C00C03442408894424148B4424142344240889C28B442414F7D02344240C09D00344241003462805B15BFFFFC1C" & _
"01103442414894424108B4424102344241489C28B442410F7D02344240809D00344240C03462C05BED75C89C1C016034424108944240C8B44240C2344241089C28B44240CF7D02344241409D003442408034630052211906BC1C0070344240C894424088B4424082344240C89C28B442408F7D02344241009D00344241403463405937198FDC1C00C03442408894424148B4424142344240889C28B442414F7D02344240C09D003442410034638058E4379A6C1C01103442414894424108B4424102344241489C28B442410F7D02344240809D00344240C03463C052108B449C1C016034424108944240C8B44240C2344241489C28B442414F7D02344241009D0034424080346040562251EF6C1C0050344240C894424088B4424082344241089C28B442410F7D02344240C09D0034424140346180540B340C0C1C00903442408894424148B4424142344240C89C28B44240CF7D02344240809D00344241003462C05515A5E26C1C00E03442414894424108B4424102344240889C28B442408F7D02344241409D00344240C030605AAC7B6E9C1C014034424108944240C8B44240C2344241489C28B442414F7D02344241009D003442408034614055D102FD6C1C0050344240C894424088B4424082344241089C28B442410F7D02344240C09D0034424140346280553144402C1C00903442408894424148B44241423" & _
"44240C89C28B44240CF7D02344240809D00344241003463C0581E6A1D8C1C00E03442414894424108B4424102344240889C28B442408F7D02344241409D00344240C03461005C8FBD3E7C1C014034424108944240C8B44240C2344241489C28B442414F7D02344241009D00344240803462405E6CDE121C1C0050344240C894424088B4424082344241089C28B442410F7D02344240C09D00344241403463805D60737C3C1C00903442408894424148B4424142344240C89C28B44240CF7D02344240809D00344241003460C05870DD5F4C1C00E03442414894424108B4424102344240889C28B442408F7D02344241409D00344240C03462005ED145A45C1C014034424108944240C8B44240C2344241489C28B442414F7D02344241009D0034424080346340505E9E3A9C1C0050344240C894424088B4424082344241089C28B442410F7D02344240C09D00344241403460805F8A3EFFCC1C00903442408894424148B4424142344240C89C28B44240CF7D02344240809D00344241003461C05D9026F67C1C00E03442414894424108B4424102344240889C28B442408F7D02344241409D00344240C034630058A4C2A8DC1C014034424108944240C8B44240C334424103344241403442408034614054239FAFFC1C0040344240C894424088B4424083344240C33442410034424140346200581F67187C1C00B034" & _
"42408894424148B442414334424083344240C0344241003462C0522619D6DC1C01003442414894424108B44241033442414334424080344240C034638050C38E5FDC1C017034424108944240C8B44240C3344241033442414034424080346040544EABEA4C1C0040344240C894424088B4424083344240C334424100344241403461005A9CFDE4BC1C00B03442408894424148B442414334424083344240C0344241003461C05604BBBF6C1C01003442414894424108B44241033442414334424080344240C0346280570BCBFBEC1C017034424108944240C8B44240C33442410334424140344240803463405C67E9B28C1C0040344240C894424088B4424083344240C3344241003442414030605FA27A1EAC1C00B03442408894424148B442414334424083344240C0344241003460C058530EFD4C1C01003442414894424108B44241033442414334424080344240C03461805051D8804C1C017034424108944240C8B44240C3344241033442414034424080346240539D0D4D9C1C0040344240C894424088B4424083344240C334424100344241403463005E599DBE6C1C00B03442408894424148B442414334424083344240C0344241003463C05F87CA21FC1C01003442414894424108B44241033442414334424080344240C034608056556ACC4C1C017034424108944240C8B442414F7D00B44240C334424" & _
"1003442408030605442229F4C1C0060344240C894424088B442410F7D00B4424083344240C0344241403461C0597FF2A43C1C00A03442408894424148B44240CF7D00B442414334424080344241003463805A72394ABC1C00F03442414894424108B442408F7D00B442410334424140344240C0346140539A093FCC1C015034424108944240C8B442414F7D00B44240C334424100344240803463005C3595B65C1C0060344240C894424088B442410F7D00B4424083344240C0344241403460C0592CC0C8FC1C00A03442408894424148B44240CF7D00B4424143344240803442410034628057DF4EFFFC1C00F03442414894424108B442408F7D00B442410334424140344240C03460405D15D8485C1C015034424108944240C8B442414F7D00B44240C3344241003442408034620054F7EA86FC1C0060344240C894424088B442410F7D00B4424083344240C0344241403463C05E0E62CFEC1C00A03442408894424148B44240CF7D00B442414334424080344241003461805144301A3C1C00F03442414894424108B442408F7D00B442410334424140344240C03463405A111084EC1C015034424108944240C8B442414F7D00B44240C334424100344240803461005827E53F7C1C0060344240C894424088B442410F7D00B4424083344240C0344241403462C0535F23ABDC1C00A03442408894424148B44240CF" & _
"7D00B442414334424080344241003460805BBD2D72AC1C00F03442414894424108B442408F7D00B442410334424140344240C0346240591D386EBC1C015034424108944240C8D7424088B7C241CB904000000AD0307ABE2FA5F5E83C410C2100090"

Private Const m_32Mul64Code As String = "578B4C24148B7C24088B44240CF7E189078957048B442410F7E10147045FC21000909090909090909090909090909090"

Private m_MD5_DigestChunkCore() As Byte
Private m_32Mul64Core() As Byte

Private Const PAGE_EXECUTE As Long = &H10
Private Const PAGE_EXECUTE_READ As Long = &H20
Private Const PAGE_EXECUTE_READWRITE As Long = &H40
Private Const PAGE_EXECUTE_WRITECOPY As Long = &H80
Private Const PAGE_NOACCESS As Long = &H1
Private Const PAGE_READONLY As Long = &H2
Private Const PAGE_READWRITE As Long = &H4
Private Const PAGE_WRITECOPY As Long = &H8
Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long

Private Declare Function BSWAPD Lib "ws2_32.dll" Alias "htonl" (ByVal Value As Long) As Long

'检测是否在IDE环境下运行
Function IsRunningInVB6IDE() As Boolean
Static Counter As Variant
If IsEmpty(Counter) Then
    Counter = 1
    Debug.Assert IsRunningInVB6IDE() Or True
    Counter = Counter - 1
ElseIf Counter = 1 Then
    Counter = 0
End If
IsRunningInVB6IDE = Counter
End Function

Private Sub InitMD5Lib()
Dim FuncLength As Long, I As Long
Dim OldProtect As Long

FuncLength = Len(m_MD5_DigestChunkCode) \ 2
ReDim m_MD5_DigestChunkCore(FuncLength - 1)
For I = 0 To FuncLength - 1
    m_MD5_DigestChunkCore(I) = CByte("&H" & Mid$(m_MD5_DigestChunkCode, 1 + I * 2, 2))
Next
VirtualProtect m_MD5_DigestChunkCore(0), FuncLength, PAGE_EXECUTE_READWRITE, OldProtect

FuncLength = Len(m_32Mul64Code) \ 2
ReDim m_32Mul64Core(FuncLength - 1)
For I = 0 To FuncLength - 1
    m_32Mul64Core(I) = CByte("&H" & Mid$(m_32Mul64Code, 1 + I * 2, 2))
Next
VirtualProtect m_MD5_DigestChunkCore(0), FuncLength, PAGE_EXECUTE_READWRITE, OldProtect
End Sub

Sub MD5_Init(Regs As MD5Reg_t)
Regs.A = &H67452301
Regs.B = &HEFCDAB89
Regs.C = &H98BADCFE
Regs.D = &H10325476
End Sub

Sub MD5_DigestChunk(Regs As MD5Reg_t, ByVal ChunkPtr As Long)
On Local Error GoTo ErrHandler

CallProcPtr m_MD5_DigestChunkCore(0), Regs, ChunkPtr, 0, 0

Exit Sub
ErrHandler:
    InitMD5Lib
    CallProcPtr m_MD5_DigestChunkCore(0), Regs, ChunkPtr, 0, 0
    Resume Next
End Sub

Sub Int64Mul32(ByVal Result_Ptr As Long, ByVal Number64_Low As Long, ByVal Number64_High As Long, ByVal Numerator As Long)
On Local Error GoTo ErrHandler
CallProcPtr m_32Mul64Core(0), ByVal Result_Ptr, Number64_Low, Number64_High, Numerator
Exit Sub
ErrHandler:
    InitMD5Lib
    CallProcPtr m_32Mul64Core(0), ByVal Result_Ptr, Number64_Low, Number64_High, Numerator
    Resume Next
End Sub

Sub MD5_TailChunk(Regs As MD5Reg_t, ByVal ChunkPtr As Long, ByVal RestLen As Long, ByVal TotalSizeLow As Long, ByVal TotalSizeHigh As Long)
Dim PadBuf(63) As Byte
If RestLen Then CopyMemory PadBuf(0), ByVal ChunkPtr, RestLen
PadBuf(RestLen) = &H80&
RestLen = RestLen + 1

If RestLen < 56 Then
    Int64Mul32 VarPtr(PadBuf(56)), TotalSizeLow, TotalSizeHigh, 8
    MD5_DigestChunk Regs, VarPtr(PadBuf(0))
Else
    MD5_DigestChunk Regs, VarPtr(PadBuf(0))
    ZeroMemory PadBuf(0), 64
    Int64Mul32 VarPtr(PadBuf(56)), TotalSizeLow, TotalSizeHigh, 8
    MD5_DigestChunk Regs, VarPtr(PadBuf(0))
End If
End Sub

Sub MD5_Sum(ByVal DataPtr As Long, ByVal DataLen As Long, MD5Out() As Long)
Dim Regs As MD5Reg_t
MD5_Init Regs

Dim CurPtr As Long
Dim RestLen As Long

CurPtr = DataPtr
RestLen = DataLen

Do While RestLen >= 64
    MD5_DigestChunk Regs, CurPtr
    CurPtr = CurPtr + 64
    RestLen = RestLen - 64
Loop

MD5_TailChunk Regs, CurPtr, RestLen, DataLen, 0

MD5Out(0) = Regs.A
MD5Out(1) = Regs.B
MD5Out(2) = Regs.C
MD5Out(3) = Regs.D
End Sub

Function MD5_ToString(MD5Hash() As Long) As String
MD5_ToString = Right$("0000000" & Hex$(BSWAPD(MD5Hash(0))), 8) & Right$("0000000" & Hex$(BSWAPD(MD5Hash(1))), 8) & Right$("0000000" & Hex$(BSWAPD(MD5Hash(2))), 8) & Right$("0000000" & Hex$(BSWAPD(MD5Hash(3))), 8)
End Function

Function MD5_String(StrSrc As String) As String
Dim Result(3) As Long
MD5_Sum StrPtr(StrSrc), LenB(StrSrc), Result
MD5_String = MD5_ToString(Result)
End Function

Function MD5_StringA(StrSrc As String) As String
Dim Result(3) As Long
If Len(StrSrc) Then
    Dim ABuf() As Byte
    ABuf = StrConv(StrSrc, vbFromUnicode)
    MD5_Sum VarPtr(ABuf(0)), UBound(ABuf) + 1, Result
Else
    MD5_Sum 0, 0, Result
End If
MD5_StringA = MD5_ToString(Result)
End Function不过,其实真正比较能看的地方就是汇编的部分,个人感觉还是可以拿出来当作典范的,因为不仅省略了帧指针,而且你还可以中途随便push pop,因为我使用一系列的宏来定位局部变量、参数等。即使我用了一万个宏,还“重写”了两个本来是指令的“指令”,但个人感觉写汇编的话这种还是属于好看的那种。bits 32

%assign Stack_Usage 0
%define Local_Var_Count 4
%define Local_Var_Size (Local_Var_Count * 4)
%define Local_Var(x) (esp + (Stack_Usage + x) * 4)
%define Param(x) (esp + (Stack_Usage + Local_Var_Count + x + 1) * 4)
%define TmpVar edx

%macro push 1
push %1
%assign Stack_Usage Stack_Usage + 1
%endmacro

%macro pop 1
pop %1
%assign Stack_Usage Stack_Usage - 1
%endmacro

;F(ret,x,y,z)
%imacro F 4
mov %1, %2
and %1, %3
mov TmpVar, %1
mov %1, %2
not %1
and %1, %4
or %1, TmpVar
%endmacro

;G(ret,x,y,z)
%imacro G 4
mov %1, %2
and %1, %4
mov TmpVar, %1
mov %1, %4
not %1
and %1, %3
or %1, TmpVar
%endmacro

;H(ret,x,y,z)
%imacro H 4
mov %1, %2
xor %1, %3
xor %1, %4
%endmacro

;I(ret,x,y,z)
%imacro I 4
mov %1, %4
not %1
or %1, %2
xor %1, %3
%endmacro

%imacro FF 8
F %1, %3, %4 ,%5
add %1, %2
add %1, %6
add %1, %8
rol %1, %7
add %1, %3
%endmacro

%imacro GG 8
G %1, %3, %4 ,%5
add %1, %2
add %1, %6
add %1, %8
rol %1, %7
add %1, %3
%endmacro

%imacro HH 8
H %1, %3, %4 ,%5
add %1, %2
add %1, %6
add %1, %8
rol %1, %7
add %1, %3
%endmacro

%imacro II 8
I %1, %3, %4 ,%5
add %1, %2
add %1, %6
add %1, %8
rol %1, %7
add %1, %3
%endmacro

;void MD5_DigestChunk(uint32_t *MD5_Registers, void *pData, void *Preserved1, void *Preserved2);
_MD5_DigestChunk@16:

sub esp, Local_Var_Size
push esi
push edi

mov esi,
lea edi,
mov ecx, 4
rep movsd

mov esi,

FF eax, , , , , , 0x07, 0xD76AA478
mov , eax
FF eax, , , , , , 0x0C, 0xE8C7B756
mov , eax
FF eax, , , , , , 0x11, 0x242070DB
mov , eax
FF eax, , , , , , 0x16, 0xC1BDCEEE
mov , eax
FF eax, , , , , , 0x07, 0xF57C0FAF
mov , eax
FF eax, , , , , , 0x0C, 0x4787C62A
mov , eax
FF eax, , , , , , 0x11, 0xA8304613
mov , eax
FF eax, , , , , , 0x16, 0xFD469501
mov , eax
FF eax, , , , , , 0x07, 0x698098D8
mov , eax
FF eax, , , , , , 0x0C, 0x8B44F7AF
mov , eax
FF eax, , , , , , 0x11, 0xFFFF5BB1
mov , eax
FF eax, , , , , , 0x16, 0x895CD7BE
mov , eax
FF eax, , , , , , 0x07, 0x6B901122
mov , eax
FF eax, , , , , , 0x0C, 0xFD987193
mov , eax
FF eax, , , , , , 0x11, 0xA679438E
mov , eax
FF eax, , , , , , 0x16, 0x49B40821
mov , eax

GG eax, , , , , , 0x05, 0xF61E2562
mov , eax
GG eax, , , , , , 0x09, 0xC040B340
mov , eax
GG eax, , , , , , 0x0E, 0x265E5A51
mov , eax
GG eax, , , , , , 0x14, 0xE9B6C7AA
mov , eax
GG eax, , , , , , 0x05, 0xD62F105D
mov , eax
GG eax, , , , , , 0x09, 0x02441453
mov , eax
GG eax, , , , , , 0x0E, 0xD8A1E681
mov , eax
GG eax, , , , , , 0x14, 0xE7D3FBC8
mov , eax
GG eax, , , , , , 0x05, 0x21E1CDE6
mov , eax
GG eax, , , , , , 0x09, 0xC33707D6
mov , eax
GG eax, , , , , , 0x0E, 0xF4D50D87
mov , eax
GG eax, , , , , , 0x14, 0x455A14ED
mov , eax
GG eax, , , , , , 0x05, 0xA9E3E905
mov , eax
GG eax, , , , , , 0x09, 0xFCEFA3F8
mov , eax
GG eax, , , , , , 0x0E, 0x676F02D9
mov , eax
GG eax, , , , , , 0x14, 0x8D2A4C8A
mov , eax

HH eax, , , , , , 0x04, 0xFFFA3942
mov , eax
HH eax, , , , , , 0x0B, 0x8771F681
mov , eax
HH eax, , , , , , 0x10, 0x6D9D6122
mov , eax
HH eax, , , , , , 0x17, 0xFDE5380C
mov , eax
HH eax, , , , , , 0x04, 0xA4BEEA44
mov , eax
HH eax, , , , , , 0x0B, 0x4BDECFA9
mov , eax
HH eax, , , , , , 0x10, 0xF6BB4B60
mov , eax
HH eax, , , , , , 0x17, 0xBEBFBC70
mov , eax
HH eax, , , , , , 0x04, 0x289B7EC6
mov , eax
HH eax, , , , , , 0x0B, 0xEAA127FA
mov , eax
HH eax, , , , , , 0x10, 0xD4EF3085
mov , eax
HH eax, , , , , , 0x17, 0x04881D05
mov , eax
HH eax, , , , , , 0x04, 0xD9D4D039
mov , eax
HH eax, , , , , , 0x0B, 0xE6DB99E5
mov , eax
HH eax, , , , , , 0x10, 0x1FA27CF8
mov , eax
HH eax, , , , , , 0x17, 0xC4AC5665
mov , eax

II eax, , , , , , 0x06, 0xF4292244
mov , eax
II eax, , , , , , 0x0A, 0x432AFF97
mov , eax
II eax, , , , , , 0x0F, 0xAB9423A7
mov , eax
II eax, , , , , , 0x15, 0xFC93A039
mov , eax
II eax, , , , , , 0x06, 0x655B59C3
mov , eax
II eax, , , , , , 0x0A, 0x8F0CCC92
mov , eax
II eax, , , , , , 0x0F, 0xFFEFF47D
mov , eax
II eax, , , , , , 0x15, 0x85845DD1
mov , eax
II eax, , , , , , 0x06, 0x6FA87E4F
mov , eax
II eax, , , , , , 0x0A, 0xFE2CE6E0
mov , eax
II eax, , , , , , 0x0F, 0xA3014314
mov , eax
II eax, , , , , , 0x15, 0x4E0811A1
mov , eax
II eax, , , , , , 0x06, 0xF7537E82
mov , eax
II eax, , , , , , 0x0A, 0xBD3AF235
mov , eax
II eax, , , , , , 0x0F, 0x2AD7D2BB
mov , eax
II eax, , , , , , 0x15, 0xEB86D391
mov , eax

lea esi,
mov edi,
mov ecx, 4
.AddOut:
lodsd
add eax,
stosd
loop .AddOut

pop edi
pop esi
add esp, Local_Var_Size

ret 16

times 16 - ($ - $$) % 16 nop


Ayala 发表于 2020-7-5 05:44:37

也可以使用ntdll的api RtlLargeInteger.........之类的移位运算

系统消息 发表于 2020-7-4 22:53:32

我之前写过VB6的位移运算模块

0xAA55 发表于 2020-7-6 15:41:50

系统消息 发表于 2020-7-4 22:53
我之前写过VB6的位移运算模块

WANTED

求分享

Ayala 发表于 2020-7-6 19:31:39

0xAA55 发表于 2020-7-6 15:41
WANTED

求分享

vb6有个内联汇编插件挺好玩的

0xAA55 发表于 2020-7-6 20:38:55

Ayala 发表于 2020-7-6 19:31
vb6有个内联汇编插件挺好玩的

哦,用过,兴趣不大。就算是现场编译,跑的时候都是必须走CallWindowProc还要传递4个参数。支持的指令也就那几个。

系统消息 发表于 2020-7-6 21:44:03

0xAA55 发表于 2020-7-6 15:41
WANTED

求分享

分享好了:https://www.0xaa55.com/thread-26026-1-1.html

Ayala 发表于 2020-7-6 23:34:38

0xAA55 发表于 2020-7-6 20:38
哦,用过,兴趣不大。就算是现场编译,跑的时候都是必须走CallWindowProc还要传递4个参数。支持的指令也 ...

看来用的不是同一个,我记得之前用的那个是外部调用ml编译的,hook的vb6,修改的build参数

0xAA55 发表于 2020-7-7 23:22:29

Ayala 发表于 2020-7-6 23:34
看来用的不是同一个,我记得之前用的那个是外部调用ml编译的,hook的vb6,修改的build参数 ...

哦。这不是常规操作么。加入自己的OBJ。

Ayala 发表于 2020-7-8 18:58:44

0xAA55 发表于 2020-7-7 23:22
哦。这不是常规操作么。加入自己的OBJ。

不过之前用的内联汇编可以任意位置内联的,除了不定参数外的函数也都支持

Private Sub foo()
'xor eax,eax
End Sub
Private Function foo(a As Integer)
    'mov eax,a
End Function
Private Function foo(a As Integer)
    Dim m, n As Integer
   
    For m = 0 To 3
      If m > 2 Then
      'mov eax,m
      'add eax,n
      'add eax,a
      End If
    Next
End Function

三种都是支持的,肯定不是单纯添加obj那么简单的东西

0xAA55 发表于 2020-7-9 01:22:10

Ayala 发表于 2020-7-8 18:58
不过之前用的内联汇编可以任意位置内联的,除了不定参数外的函数也都支持

Private ...

这个有点厉害啊!

Ayala 发表于 2020-7-9 08:44:34

0xAA55 发表于 2020-7-9 01:22
这个有点厉害啊!

不知道怎么实现的,我有个大体思路,源代码有asm部分填充无用的有特征性的vb代码,然后编译生成asm文件,将特征部分的代码改成内联汇编代码(符号部分处理起来一点也不简单,需要很清楚了解vb的各种符号,可能需要启发式搜索引擎)然后再编译
页: [1]
查看完整版本: 【VB】VB6+ASM实现MD5计算