VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
查看: 5775|回复: 9

[转帖] 如何获取VB编译后的LST文件

[复制链接]
 楼主| 发表于 2009-8-7 07:22:51 | 显示全部楼层 |阅读模式
如何获取VB编译后的LST文件

说明
什么是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
  
文件出处
Honey
整理时间
2003,4,30

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

本帖被以下淘专辑推荐:

 楼主| 发表于 2009-8-7 07:40:57 | 显示全部楼层
这个文章是在台湾的一个VB站点 CWW的VB心得?? 里看到的,觉得很不错,论坛里也没发过,就给转来了,有注明原贴地址。
回复 支持 反对

使用道具 举报

发表于 2009-8-7 09:09:43 | 显示全部楼层
繁体字,看的累
回复 支持 反对

使用道具 举报

发表于 2009-8-7 09:20:23 | 显示全部楼层
新林辛苦了!好文章一定仔细阅读.
回复 支持 反对

使用道具 举报

发表于 2009-8-7 11:00:53 | 显示全部楼层
vb的汇编插件大多都是利用这个参数.

比如: tweakvb
回复 支持 反对

使用道具 举报

发表于 2009-8-7 17:20:09 | 显示全部楼层
不知道得到这个文件有什么实际用处吗?我不懂汇编..
回复 支持 反对

使用道具 举报

发表于 2009-8-7 23:27:34 | 显示全部楼层
我是用生成符号化调试信息(pdb)的……这样编译了之后就算非法操作也可以在VS2005里面调试,然后就会自动加载源代码……
回复 支持 反对

使用道具 举报

发表于 2010-9-21 00:15:50 | 显示全部楼层
水平太低,完全看不懂,先做个记号
回复 支持 反对

使用道具 举报

发表于 2010-9-26 11:06:28 | 显示全部楼层
一样。。我也看不懂。。水平低。。学习。。
回复 支持 反对

使用道具 举报

发表于 2010-9-26 16:30:18 | 显示全部楼层
修改编译参数要不就是连接参数,我也忘了,拦截动作,修改参数,指定输出位置,继续编译就出来了,具体参数是哪个我也忘了,自己查查,要么问问书林还记得没
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2022-7-4 05:18

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表