1.环境变量
按用途可分为:与系统运行相关、反应系统状态以及应用程序自定义三种环境变量
操作函数:
获取一个环境变量的值:GetEnvironmentVariable
设置新变量或删除已有变量 :SetEnvironmentVariable (仅改变本进程的环境变量)
枚举所有的环境变量:GetEnvironmentStrings
释放环境变量的拷贝:FreeEnvironmentStrings
2.命令行参数:某些情况下,命令行参数是窗口程序的必然补充,如:关联文件
操作函数:
获取命令行参数:GetCommanLine (Windows以空格区分参数,所以应注意双引号引起的问题)
3.1 Shell 调用(创建了新进程,但控制不了)
WinExec
ShellExecute
3.2 创建进程(可进行后续控制)
进程被创建时,系统的操作:创建一个内核对象和一个虚拟地址空间以及一个主线程
涉及结构:
STARTUPINFO
PROCESS_INFORMATION
涉及函数:
获取当期进程的 STARTUPINFO :GetStartUp
创建进程:CreateProcess
结束进程:ExitProcess
获取退出码:GetExitCodeProcess
结束其他进程:TerminateProcess
进程被结束时,系统的操作:
(1)关闭进程创建或打开的所有对象句柄
(2)终止进程中的所有线程
(3)进程及进程中所有线程的状态被改为置位状态,以便让WaitSingleObject 函数正确检测
(4)进程对象中的退出码字段从 STILL_ACTIVE 被改为指定的退出码
PS:进程结束不影响子进程,直到使用CloseHandle 将进程句柄关闭后,进程对象才真正被删除。当不再需要进程句柄的时候,记得关闭PROCESS_INFORMATION结构中返回的进程句柄和主线程句柄。
示例如下:
按用途可分为:与系统运行相关、反应系统状态以及应用程序自定义三种环境变量
操作函数:
获取一个环境变量的值:GetEnvironmentVariable
设置新变量或删除已有变量 :SetEnvironmentVariable (仅改变本进程的环境变量)
枚举所有的环境变量:GetEnvironmentStrings
释放环境变量的拷贝:FreeEnvironmentStrings
2.命令行参数:某些情况下,命令行参数是窗口程序的必然补充,如:关联文件
操作函数:
获取命令行参数:GetCommanLine (Windows以空格区分参数,所以应注意双引号引起的问题)
PS:Win32中CommandLineToArgvW 可以扫描字符串,但仅适合Unicode 和 WinNT ,因此,我们自己编写一个获取命令行参数的通用函数,代码如下:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; _CmdLine.asm
; 命令行参数分析的通用子程序
; 功能:
; _argc ---> 对命令行参数进行数量统计
; _argv ---> 取某个命令行参数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CHAR_BLANK equ 20h ;定义空格
CHAR_DELI equ '"' ;定义分隔符
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 取命令行参数个数 (arg count)
; 参数个数必定大于等于 1, 参数 1 为当前执行文件名
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_argc proc
local @dwArgc ;参数个数
pushad
mov @dwArgc,0
invoke GetCommandLine
mov esi,eax
cld
_argc_loop:
;********************************************************************
; 忽略参数之间的空格
;********************************************************************
lodsb
or al,al
jz _argc_end ;无输入或到字符串尾
cmp al,CHAR_BLANK
jz _argc_loop ;空格则忽略
;********************************************************************
; 一个参数开始
;********************************************************************
dec esi ;
inc @dwArgc
_argc_loop1:
lodsb
or al,al
jz _argc_end ;无输入或到字符串尾
cmp al,CHAR_BLANK
jz _argc_loop ;空格则忽略
cmp al,CHAR_DELI
jnz _argc_loop1 ;引号,继续处理参数内容
;********************************************************************
; 如果一个参数中的一部分有空格,则用 " " 包括
;********************************************************************
@@:
lodsb
or al,al
jz _argc_end ;无输入或到字符串尾
cmp al,CHAR_DELI ;直到遇到另一个引号为止
jnz @B
jmp _argc_loop1
_argc_end:
popad
mov eax,@dwArgc
ret
_argc endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 取指定位置的命令行参数
; argv 0 = 执行文件名
; argv 1 = 参数1 ...
; 参数含义:参数编号,接收参数缓冲区,缓冲区大小
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_argv proc _dwArgv,_lpReturn,_dwSize
local @dwArgv,@dwFlag
pushad
inc _dwArgv
mov @dwArgv,0
mov edi,_lpReturn ;目的串
invoke GetCommandLine
mov esi,eax
cld
_argv_loop:
;********************************************************************
; 忽略参数之间的空格
;********************************************************************
lodsb
or al,al
jz _argv_end
cmp al,CHAR_BLANK
jz _argv_loop ;同上
;********************************************************************
; 一个参数开始
; 如果和要求的参数符合,则开始复制到返回缓冲区
;********************************************************************
dec esi
inc @dwArgv
mov @dwFlag,FALSE
mov eax,_dwArgv
cmp eax,@dwArgv
jnz @F
mov @dwFlag,TRUE ;表示需要将字符返回
@@:
_argv_loop1:
lodsb
or al,al
jz _argv_end
cmp al,CHAR_BLANK
jz _argv_loop ;参数结束
cmp al,CHAR_DELI
jz _argv_loop2
cmp _dwSize,1 ;如果返回缓冲区满则返回
jle @F
cmp @dwFlag,TRUE
jne @F
stosb
dec _dwSize
@@:
jmp _argv_loop1 ;继续处理参数内容
_argv_loop2:
lodsb
or al,al
jz _argv_end
cmp al,CHAR_DELI
jz _argv_loop1
cmp _dwSize,1 ;如果返回缓冲区满则返回
jle @F
cmp @dwFlag,TRUE
jne @F
stosb
dec _dwSize
@@:
jmp _argv_loop2
_argv_end:
xor al,al
stosb ;0结束
popad
ret
_argv endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
3.可执行文件的执行3.1 Shell 调用(创建了新进程,但控制不了)
WinExec
ShellExecute
3.2 创建进程(可进行后续控制)
进程被创建时,系统的操作:创建一个内核对象和一个虚拟地址空间以及一个主线程
涉及结构:
STARTUPINFO
PROCESS_INFORMATION
涉及函数:
获取当期进程的 STARTUPINFO :GetStartUp
创建进程:CreateProcess
结束进程:ExitProcess
获取退出码:GetExitCodeProcess
结束其他进程:TerminateProcess
进程被结束时,系统的操作:
(1)关闭进程创建或打开的所有对象句柄
(2)终止进程中的所有线程
(3)进程及进程中所有线程的状态被改为置位状态,以便让WaitSingleObject 函数正确检测
(4)进程对象中的退出码字段从 STILL_ACTIVE 被改为指定的退出码
PS:进程结束不影响子进程,直到使用CloseHandle 将进程句柄关闭后,进程对象才真正被删除。当不再需要进程句柄的时候,记得关闭PROCESS_INFORMATION结构中返回的进程句柄和主线程句柄。
示例如下:
.data?
stStartUp STARTUPINFO <?>
stProcInfo PROCESS_INFORMATION <?>
.code
invoke lstrcpy,addr @szBuffer,addr szFileName
.if szCmdLine
invoke lstrcat,addr @szBuffer,addr szBlank
invoke lstrcat,addr @szBuffer,addr szCmdLine
.endif
;********************************************************************
; 创建进程
;********************************************************************
invoke GetStartupInfo,addr stStartUp
invoke CreateProcess,NULL,addr @szBuffer,NULL,NULL,NULL,\
NORMAL_PRIORITY_CLASS,NULL,NULL,addr stStartUp,addr stProcInfo
.if eax
;********************************************************************
; 等待进程结束
;********************************************************************
invoke WaitForSingleObject,stProcInfo.hProcess,INFINITE
invoke CloseHandle,stProcInfo.hProcess
invoke CloseHandle,stProcInfo.hThread
.else
invoke MessageBox,hWinMain,addr szErrExec,NULL,MB_OK or MB_ICONWARNING
.endif