什么是lst文件呢? 对于VB的使用者而言的确是陌生了点,其它编译器通常会有lst文件的输出选项,lst文件会将原始程序以及编译后的汇编语言一同输出,内容大概是这样
?Form_Load@Form1@@AAGXXZ PROC NEAR ; Form1::Form_Load, COMDAT
; 84 : Private Sub Form_Load()
push ebp
mov ebp, esp
sub esp, 12 ;0000000cH
push OFFSET FLAT:___vbaExceptHandler
mov eax, DWORD PTR fs:__except_list
push eax
mov DWORD PTR fs:__except_list, esp
sub esp, 136 ; 00000088H
push ebx
push esi
push edi
mov DWORD PTR __$SEHRec$[ebp+8], esp
mov DWORD PTR __$SEHRec$[ebp+12], OFFSET FLATS39
mov ebx, DWORD PTR _Me$[ebp]
mov eax, ebx
and eax, 1
mov DWORD PTR __$SEHRec$[ebp+16], eax
and ebx, -2 ; fffffffeH
push ebx
mov DWORD PTR _Me$[ebp], ebx
mov ecx, DWORD PTR [ebx]
call DWORD PTR [ecx+4]
; 85 : Dim inj As Long, i As Long
; 86 :
; 87 : comString = Command
lea edx, DWORD PTR _unnamed_var1$[ebp]
xor esi, esi
push edx
mov DWORD PTR _unnamed_var1$[ebp], esi
mov DWORD PTR _unnamed_var1$[ebp], esi
mov DWORD PTR _unnamed_var1$[ebp], esi
mov DWORD PTR _unnamed_var1$[ebp], esi
mov DWORD PTR _unnamed_var1$[ebp], esi
mov DWORD PTR _unnamed_var1$[ebp], esi
mov DWORD PTR _unnamed_var1$[ebp], esi
mov DWORD PTR _unnamed_var1$[ebp], esi
call DWORD PTR __imp____vba@001E714C
lea eax, DWORD PTR _unnamed_var1$[ebp]
add ebx, 64 ; 00000040H
push eax
call DWORD PTR __imp____vbaStrVarMove
mov edx, eax
lea ecx, DWORD PTR _unnamed_var1$[ebp]
call DWORD PTR __imp_@__vbaStrMove
mov edx, eax
mov ecx, ebx
call DWORD PTR __imp_@__vbaStrCopy
lea ecx, DWORD PTR _unnamed_var1$[ebp]
call DWORD PTR __imp_@__vbaFreeStr
lea ecx, DWORD PTR _unnamed_var1$[ebp]
call DWORD PTR __imp_@__vbaFreeVar
; 88 :
; 89 : inj = InStr(LCase(comString), ".obj""")
lea ecx, DWORD PTR _unnamed_var1$[ebp]
lea edx, DWORD PTR _unnamed_var1$[ebp]
push ecx
push edx
mov DWORD PTR _unnamed_var1$[ebp+8], ebx
mov DWORD PTR _unnamed_var1$[ebp], 16392 ; 00004008H
call DWORD PTR __imp____vba@001F10A4
lea eax, DWORD PTR _unnamed_var1$[ebp]
push 1
lea ecx, DWORD PTR _unnamed_var1$[ebp]
push eax
push ecx
lea edx, DWORD PTR _unnamed_var1$[ebp]
push esi
push edx
mov DWORD PTR _unnamed_var1$[ebp+8], OFFSET FLAT:___vba@001F1F2C
mov DWORD PTR _unnamed_var1$[ebp], 8
call DWORD PTR __imp____vbaInStrVar
push eax
call DWORD PTR __imp____vbaI4Var
mov edi, eax
lea eax, DWORD PTR _unnamed_var1$[ebp]
lea ecx, DWORD PTR _unnamed_var1$[ebp]
push eax
push ecx
push 2
:
:
透过这个文件,我们可以很清楚的知道程序编译的结果,由于VB是个经过多层包装,例如上例可以发现InStr这个函数底层是透过调用 __imp____vbaInStrVar去做的.
但是VB的编译并不是使用者能控制的,他交给VB6.exe去处理,你可以试着调用E:\Program Files\Microsoft Visual Studio\VB98\VB6.EXE/?
后方加个/?的参数 会显示出以下窗口
但也是仅限于编译VBP文件,并不能输出LST文件,我们必须探讨到更底层,VB6.EXE再编译执行文件时有几个步骤
1.产生一些中继文件
2.透过CreateProcess 调用C2.EXE 将所有Form,模块,对象等等编译成OBJ文件
3.透过CreateProcess 调用Link.EXE 将所有OBJ文件链接成EXE文件
因此,我们只要对C2.EXE动手脚就行了,我的做法是这样
1.先将E:\ProgramFiles\Microsoft Visual Studio\VB98\C2.EXE
改名为E:\Program Files\Microsoft Visual Studio\VB98\C3.EXE
注意 路径可能跟我的不同
2.下载C2.Zip
3.解压缩后将内部的C2.EXE放到目录E:\ProgramFiles\Microsoft Visual Studio\VB98\底下
然后就可以用VB来编译程序了 ,每编译一个文件,都会出现以下窗口
按下开始编译后就可以在Text内的路径下得到该lst文件
如果不想输出lst文件,只要将产生lst文件的选项拿掉即可
这个程序调用原C2.EXE(已经改名为C3.EXE)来编译成OBJ文件 中间额外加入 -FAs -Fa"C:\Documenuts andSettings\陈骏\桌面\Form1.lst" 这段参数
其中-FAs是指定要输出lst文件 -Fa用来指定lst输出文件名
这个参数是未公开的
完整程序如下
程序
'以下程序在Form中
'需要1个Text,1个Command,1个CheckBox,如上图
Option Explicit
Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" _
(ByVal hProcess As Long, lpExitCode As Long) As Long
Const PROCESS_QUERY_INFORMATION = &H400
Const SYNCHRONIZE = &H100000
Const STILL_ALIVE = &H103
Const INFINITE = &HFFFF
Dim ExitCode As Long
Dim hProcess As Long
Dim lst_FileName As String
Dim comString As String
Private Sub Form_Load()
Dim inj As Long, i As Long
comString = Command
inj = InStr(LCase(comString), ".obj""")
For i = inj To 1 Step -1
If Mid(comString, i, 1) = """" Then
lst_FileName = Mid(comString, i + 1,inj - i)
Exit For
End If
Next
Text1.Text = lst_FileName & "lst"
End Sub
Private Sub Command1_Click()
Dim pid As Long
Command1.Enabled = False
Me.Hide
DoEvents
If Check1.Value Then
pid = Shell("c3 " & comString & "-FAs -Fa""" & Text1.Text & """",vbHide)
Else
pid = Shell("c3 " & comString, vbHide)
End If
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION + SYNCHRONIZE, 0, pid)
Do
Call GetExitCodeProcess(hProcess, ExitCode)
DoEvents
Loop While ExitCode = STILL_ALIVE
Call CloseHandle(hProcess)
Unload Me
End Sub
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
上传的附件: