This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Tools/VerStamp/VerStamp.asm

1235 lines
36 KiB
NASM
Raw Permalink Normal View History

;
; Command & Conquer Renegade(tm)
; Copyright 2025 Electronic Arts Inc.
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
;
;***********************************************************************************************
;*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
;***********************************************************************************************
;* *
;* Project Name : Command & Conquer *
;* *
;* $Archive:: /Commando/Code/Tools/VerStamp/VerStamp.asm $*
;* *
;* $Author:: Steve_t $*
;* *
;* $Modtime:: 12/05/01 1:02a $*
;* *
;* $Revision:: 4 $*
;* *
;*---------------------------------------------------------------------------------------------*
;* Functions: *
;* *
;* main_ -- Program entry point. Does most of the work *
;* Print -- Prints a string to stdout *
;* Alloc -- Allocate memory from the heap *
;* Free -- Free memory *
;* Search_Buffer -- Search a buffer for occurance of given data *
;* Get_Build -- Load and update the build number *
;* *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
;
; Why is this written in assembly language when C++ would clearly be more appropriate?
; Because I can and I need the practice.
;
; Anyone offended should feel free to rewrite it in C++.
;
.686
.k3d
.mmx
.model flat
;***********************************************************************************************
; Prototypes for Win32 API calls.
;
; Printing
;
OutputDebugString proto STDCALL string:ptr byte
GetStdHandle proto STDCALL handle_type:dword
WriteConsole proto STDCALL handle:dword, string:ptr byte, numchars:dword, charswritten:ptr dword, reserved:ptr dword
; File functions
;
CloseHandle proto STDCALL handle:dword
CreateFile proto STDCALL file_name:ptr byte, access_mode:dword, share_mode:dword, sec_attr:ptr byte, creation_disposition:dword, flags:dword, template:dword
GetFileSize proto STDCALL handle:dword, file_size_high:ptr dword
ReadFile proto STDCALL handle:dword, buffer:ptr byte, bytes_to_read:dword, bytes_read:ptr dword, overlapped:ptr byte
GetFileTime proto STDCALL handle:dword, create_time:ptr dword, access_time:ptr dword, write_time:ptr dword
SetFileTime proto STDCALL handle:dword, create_time:ptr dword, access_time:ptr dword, write_time:ptr dword
FileTimeToLocalFileTime proto STDCALL utc_time:ptr dword, local_time:ptr dword
SetFilePointer proto STDCALL handle:dword, distance:dword, dist_high:ptr dword, method:dword
WriteFile proto STDCALL handle:dword, buffer:ptr byte, bytes:dword, bytes_written:ptr dword, overlapped:ptr byte
; Heap functions
;
HeapAlloc proto STDCALL handle:dword, flags:dword, bytes:dword
HeapFree proto STDCALL handle:dword, flags:dword, memptr:ptr byte
HeapCreate proto STDCALL flags:dword, startsize:dword, maxsize:dword
HeapDestroy proto STDCALL handle:dword
; Misc APIs
;
GetUserName proto STDCALL buffer:ptr byte, buffer_len:ptr dword
GetCommandLine proto STDCALL
;***********************************************************************************************
; Local prototypes.
;
Search_Buffer proto C source_ptr:ptr byte, dest_ptr:ptr byte, source_len:dword, dest_len:dword
main proto STDCALL
Parse_Command_Line proto C
String_To_Int proto C
;***********************************************************************************************
; Externs for linking to Win32 APIs
;
externdef __imp__CreateFileA@28:dword
externdef __imp__GetFileSize@8:dword
externdef __imp__CloseHandle@4:dword
externdef __imp__OutputDebugStringA@4:dword
externdef __imp__GetStdHandle@4:dword
externdef __imp__WriteConsoleA@20:dword
externdef __imp__HeapAlloc@12:dword
externdef __imp__HeapFree@12:dword
externdef __imp__HeapCreate@12:dword
externdef __imp__HeapDestroy@4:dword
externdef __imp__ReadFile@20:dword
externdef __imp__WriteFile@20:dword
externdef __imp__GetFileTime@16:dword
externdef __imp__SetFileTime@16:dword
externdef __imp__FileTimeToLocalFileTime@8:dword
externdef __imp__SetFilePointer@16:dword
externdef __imp__GetUserNameA@8:dword
externdef __imp__GetCommandLineA@0:dword
;***********************************************************************************************
; Equates
;
STD_OUTPUT_HANDLE equ -11
INVALID_HANDLE_VALUE equ -1
FILE_BEGIN equ 0
;***********************************************************************************************
; Data segment.
;
.data
StandardOutput dd INVALID_HANDLE_VALUE
Scrap dd 0
FileHandle dd INVALID_HANDLE_VALUE
ExeAddr dd 0
ExeSize dd 0
BuildStampAddr dd 0
DateStampAddr dd 0
ProcessHeap dd 0
BuildNumber dd 0
ChunkSize dd 0
BuildNumberSpecified dd 0
FileTimeWrite dd 0,0
FileTimeCreate dd 0,0
FileTimeAccess dd 0,0
LocalFileTime dd 0,0
MyFileName db 256 dup (0)
FileName db "renegade.exe",0
db 256 dup (0)
BuildNumberFileName db ".\build.bin",0
db 256 dup (0)
FileNameList dd FileName,BuildNumberFileName
Args db 256 dup (0)
ArgumentList dd 8 dup (0)
IDString db "VerStamp - Version stamping utility for Renegade",13,10
db "Version 1.2",13,10
db "Programmer - Steve T.",13,10
db "Usage: VerStamp options <path to exe> <path to build number file>",13,10
db " Options: -n<num> set build number",13,10
db 0
SearchingString db "Opening target .EXE",13,10,0
OpenFailedString db "Failed to open target .EXE - aborting.",13,10,0
SizeFailedString db "Unable to get size of target .EXE - aborting",13,10,0
NoMemString db "Out of memory - aborting",13,10,0
ReadFailureString db "Error reading target .EXE - aborting",13,10,0
ReadOKString db "Target .EXE read OK",13,10,0
StampNotFound db "Unable to find stamp signature in target .exe",13,10,0
BuildStampFound db "Found build stamp signature in target .exe",13,10,0
DateStampFound db "Found date stamp signature in target .exe",13,10,0
FileTimeFailedString db "Unable to get time of last modification to target .EXE - aborting",13,10,0
WritingString db "Modifying target .EXE",13,10,0
FilePointerFailedString db "Failed to set file pointer - aborting",13,10,0
LoadingBuildString db "Reading build number from build file",13,10,0
ReadBuildFailureString db "Error reading build file - setting build numnber to 1",13,10,0
UnrecognisedOption db "Unrecognised command line option",13,10,0
align 4
BuildNumberSearchString db "Insert1Build2Number3Here4 ",0
align 4
BuildDateSearchString db "Insert1Build2Date3Here4 ",0
;***********************************************************************************************
; Code Segment
;
;
_text segment para public use32 'CODE'
org 0
;***********************************************************************************************
;* main_ -- Program entry point *
;* *
;* *
;* INPUT: Usual command line stuff *
;* *
;* *
;* OUTPUT: Exit code *
;* *
;* *
;* HISTORY: *
;* 10/19/98 10:43PM ST : Created. *
;*=============================================================================================*
externdef main :near
main proc STDCALL
pushad
cld
;invoke OutputDebugString, ADDR TestString
;
; Get the standard console output handle.
;
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov [StandardOutput],eax
lea eax,IDString
call Print
;
; Create a 32Mb heap for the process so we can allocate memory. Allow it to grow if needed.
;
invoke HeapCreate, 0, 33554432, 0
mov [ProcessHeap],eax
test eax,eax
jnz @@heap_ok
lea eax,NoMemString
call Print
mov eax,1
jmp @@out
@@heap_ok: ;
; Parse the command line.
;
call Parse_Command_Line
;
; Read in the build number
;
call Get_Build
;
; Open RENEGADE.EXE
;
lea eax,SearchingString
call Print
invoke CreateFile, ADDR FileName, 80000000h, 1h, 0, 3h, 80h, 0
mov [FileHandle],eax
;
; Check the file handle and bail if it's bad.
;
cmp eax,INVALID_HANDLE_VALUE
jnz @@file_open_ok
lea eax,OpenFailedString
call Print
mov eax,1
jmp @@out
@@file_open_ok:
;
; Get the time the file was last modified.
;
invoke GetFileTime, FileHandle, ADDR FileTimeCreate, ADDR FileTimeAccess, ADDR FileTimeWrite
test eax,eax
jnz @@got_file_time
lea eax,FileTimeFailedString
call Print
mov eax,1
jmp @@out
@@got_file_time:
;
; Convert it to the local time.
;
invoke FileTimeToLocalFileTime, ADDR FileTimeWrite, ADDR LocalFileTime
;
; Get the size of RENEGADE.EXE
;
invoke GetFileSize, FileHandle, 0
mov [ExeSize],eax
cmp eax,0ffffffffh
jnz @@size_ok
lea eax,SizeFailedString
call Print
mov eax,1
jmp @@out
;
; Allocate a buffer to load the file into.
;
@@size_ok: add eax,1024
call Alloc
test eax,eax
jnz @@got_buffer
lea eax,NoMemString
call Print
mov eax,1
jmp @@out
@@got_buffer: mov [ExeAddr],eax
mov [ChunkSize],1048576
call Search_By_Chunk
mov [BuildStampAddr],eax
;
; Close the file.
;
push eax
mov edx,[FileHandle]
invoke CloseHandle, edx
pop eax
;
; See if we found the build string.
;
test eax,eax
jnz @@found_build_number
lea eax,StampNotFound
call Print
mov eax,1
jmp @@out
@@found_build_number:
lea eax,BuildStampFound
call Print
;
; Write the build number into place.
;
mov edi,[BuildStampAddr]
mov eax,[BuildNumber]
lea edi,[edi+28]
stosd
;
; Write the users name into place
;
mov [Scrap],32
invoke GetUserName, edi, ADDR Scrap
;
; Try to find the build date stamp in the .EXE
; It is probably near the first stamp so just back up a little and try from there.
;
mov eax,[BuildStampAddr]
sub eax,1024
mov ebx,eax
sub ebx,[ExeAddr]
neg ebx
add ebx,[ExeSize]
invoke Search_Buffer, ADDR BuildDateSearchString, eax, 28, ebx
test eax,eax
jnz @@found_build_date
lea eax,StampNotFound
call Print
mov eax,1
jmp @@out
@@found_build_date:
mov [DateStampAddr],eax
lea eax,DateStampFound
call Print
;
; Move the build date into the stamp location.
;
mov edi,[DateStampAddr]
lea edi,[edi+28]
mov esi,offset LocalFileTime
movsd
movsd
;
; Open RENEGADE.EXE again so we can write the changes back out.
;
lea eax,WritingString
call Print
invoke CreateFile, ADDR FileName, 40000000h, 1h, 0, 3h, 80h, 0
mov [FileHandle],eax
cmp eax,INVALID_HANDLE_VALUE
jnz @@open_for_write
lea eax,OpenFailedString
call Print
mov eax,1
jmp @@out
@@open_for_write:
;
; Write out the changes made at the build stamp address
;
mov eax,[BuildStampAddr]
add eax,28
push eax
sub eax,[ExeAddr]
push eax
invoke SetFilePointer, FileHandle, eax, 0, FILE_BEGIN
pop ebx
cmp eax,ebx
pop esi
jz @@fp_set_ok1
lea eax,FilePointerFailedString
call Print
mov eax,1
jmp @@out
;
; Write out the changes made at the build date address
;
@@fp_set_ok1: invoke WriteFile, FileHandle, esi, 36, ADDR Scrap, 0
mov eax,[DateStampAddr]
add eax,28
push eax
sub eax,[ExeAddr]
push eax
invoke SetFilePointer, FileHandle, eax, 0, FILE_BEGIN
pop ebx
cmp eax,ebx
pop esi
jz @@fp_set_ok2
lea eax,FilePointerFailedString
call Print
mov eax,1
jmp @@out
@@fp_set_ok2: invoke WriteFile, FileHandle, esi, 8, ADDR Scrap, 0
;
; Set the file time back to what it was before we modified the file.
;
invoke SetFileTime, FileHandle, ADDR FileTimeCreate, ADDR FileTimeAccess, ADDR FileTimeWrite
;
; Close the file.
;
mov eax,[FileHandle]
invoke CloseHandle, eax
;
; Free the memory used by the image.
;
mov eax,[ExeAddr]
call Free
;
; Success!
;
xor eax,eax
@@out: mov ebx,[ProcessHeap]
test ebx,ebx
jz @@no_heap_free
push eax
invoke HeapDestroy, ebx
pop eax
@@no_heap_free: popad
ret
main endp
;***********************************************************************************************
;* Print -- Prints out a string to standard output *
;* *
;* *
;* INPUT: eax - string *
;* *
;* *
;* OUTPUT: true if string printed OK *
;* *
;* *
;* HISTORY: *
;* 10/19/98 11:12PM ST : Created. *
;*=============================================================================================*
Print proc
;
; Check the std out handle for validity
;
cmp [StandardOutput], INVALID_HANDLE_VALUE
jnz @@handle_ok
xor eax,eax
ret
@@handle_ok: ;
; Count the number of characters in the string.
;
mov esi,eax
xor dl,dl
@@loop: cmp [esi],dl
jz @@counted
inc esi
jmp @@loop
;
; Use the WriteConsole API to output the string.
;
@@counted: mov ecx,esi
sub ecx,eax
push ecx
invoke WriteConsole, StandardOutput, eax, ecx, ADDR Scrap, 0
pop ecx
xor eax,eax
cmp ecx,[Scrap]
sete al
ret
Print endp
;***********************************************************************************************
;* Alloc -- Allocate given number of bytes from the heap *
;* *
;* *
;* INPUT: eax - bytes to allocate *
;* *
;* *
;* OUTPUT: ptr to allocated memory *
;* *
;* *
;* HISTORY: *
;* 10/20/98 0:24AM ST : Created. *
;*=============================================================================================*
Alloc proc
;
; Make sure the heap is valid.
;
mov edx,[ProcessHeap]
test edx,edx
jnz @@alloc_heap_valid
xor eax,eax
ret
;
; Try to allocate the memory.
;
@@alloc_heap_valid:
invoke HeapAlloc, edx, 0, eax
ret
Alloc endp
;***********************************************************************************************
;* Free -- Free a previously allocated block of memory *
;* *
;* *
;* INPUT: eax - ptr to memory to free *
;* *
;* *
;* OUTPUT: nothing *
;* *
;* *
;* HISTORY: *
;* 10/20/98 0:23AM ST : Created. *
;*=============================================================================================*
Free proc
;
; Make sure the heap is valid.
;
mov edx,[ProcessHeap]
test edx,edx
jnz @@free_heap_valid
xor eax,eax
ret
@@free_heap_valid:
invoke HeapFree, edx, 0, eax
ret
Free endp
;***********************************************************************************************
;* Search -- Find first occurrance of source data in buffer *
;* *
;* *
;* INPUT: ptr to data to search for *
;* ptr to buffer *
;* length of search data *
;* size of buffer *
;* *
;* OUTPUT: ptr to data match in buffer or null *
;* *
;* Warning: Source data must be multiple of 4 bytes long *
;* *
;* HISTORY: *
;* 10/20/98 0:23AM ST : Created. *
;*=============================================================================================*
Search_Buffer proc C uses esi edi ebx ecx edx,
source_ptr:ptr byte,
dest_ptr:ptr byte,
source_len:dword,
dest_len:dword
mov edi,[dest_ptr]
mov esi,[source_ptr]
mov edx,[dest_len]
sub edx,[source_len]
shr [source_len],2
test edx,edx
jz @@failed
mov eax,esi
mov ebx,edi
@@outer_loop: mov ecx,[source_len]
mov esi,eax
mov edi,ebx
repz cmpsd
jz @@found
inc ebx
dec edx
cmp edx,[source_len]
jae @@outer_loop
@@failed: xor eax,eax
ret
@@found: mov eax,ebx
ret
Search_Buffer endp
;***********************************************************************************************
;* Search_By_Chunk -- Find first occurrance of source data in file *
;* *
;* *
;* INPUT: Nothing *
;* *
;* OUTPUT: ptr to data match in buffer or null *
;* *
;* Warning: None *
;* *
;* HISTORY: *
;* 10/29/2001 12:39PM ST : Created. *
;*=============================================================================================*
Search_By_Chunk proc C uses esi edi ebx ecx edx,
;
; Read the file in chunks. Search for the matching string in each chunk before loading the next.
;
xor ebx,ebx ; Chunk number
@@next_chunk:
mov eax,ebx
mov ecx,[ChunkSize]
imul eax,ecx
cmp eax,[ExeSize]
jae @@str_not_found
mov edx,[ExeSize]
sub edx,eax
cmp edx,ecx
jae @@no_overrun
mov ecx,edx
test ecx,ecx
jz @@str_not_found
;
; Read a chunk of the file.
;
@@no_overrun: add eax,[ExeAddr]
push eax
push ebx
push ecx
invoke ReadFile, FileHandle, eax, ecx, ADDR Scrap, 0
pop ecx
pop ebx
pop esi
test eax,eax
jnz @@read_ok
lea eax,ReadFailureString
call Print
jmp @@str_not_found
;
; Search this chunk.
;
@@read_ok: push ecx
test ebx,ebx
jz @@skip_if_first
sub esi,32
add ecx,32
@@skip_if_first:invoke Search_Buffer, ADDR BuildNumberSearchString, esi, 28, ecx
pop ecx
test eax,eax
jne @@found_string
cmp ecx,[ChunkSize]
jl @@str_not_found
inc ebx ; Chunk number
jmp @@next_chunk
@@str_not_found:xor eax,eax
@@found_string: ret
Search_By_Chunk endp
;***********************************************************************************************
;* Get_Build -- Load and update the build number *
;* *
;* *
;* INPUT: nothing *
;* *
;* OUTPUT: new build number *
;* *
;* Warning: Source data must be multiple of 4 bytes long *
;* *
;* HISTORY: *
;* 10/20/98 0:23AM ST : Created. *
;*=============================================================================================*
Get_Build proc
cmp [BuildNumberSpecified],0
jnz @@already_got_bn
lea eax,LoadingBuildString
call Print
invoke CreateFile, ADDR BuildNumberFileName, 80000000h, 1h, 0, 3h, 80h, 0
mov [FileHandle],eax
;
; Check the file handle and dont read if it's bad.
;
cmp eax,INVALID_HANDLE_VALUE
jnz @@load_ok
;
; There was an error so print a message.
;
lea eax,ReadBuildFailureString
call Print
jmp @@load_done
@@load_ok: invoke ReadFile, FileHandle, ADDR BuildNumber, 4, ADDR Scrap, 0
invoke CloseHandle, FileHandle
;
; Increment the build number
;
@@load_done: inc BuildNumber
;
; Write it out again.
;
invoke CreateFile, ADDR BuildNumberFileName, 40000000h, 1h, 0, 4h, 80h, 0
mov [FileHandle],eax
invoke WriteFile, FileHandle, ADDR BuildNumber, 4, ADDR Scrap, 0
invoke CloseHandle, FileHandle
@@already_got_bn:
ret
Get_Build endp
;***********************************************************************************************
;* Break_Command_Line -- Break the command line into seperate args *
;* *
;* *
;* INPUT: Nothing *
;* *
;* OUTPUT: Nothing *
;* *
;* Warning: None *
;* *
;* HISTORY: *
;* 10/29/2001 12:39PM ST : Created. *
;*=============================================================================================*
Break_Command_Line proc C
local arguments:dword
local done:dword
local argslen:dword
mov [arguments],0
mov [done],0
mov [argslen],0
;
; Get a pointer to the command line.
;
invoke GetCommandLine
mov esi,eax
;
; Command line ptr is esi
;
@@cmd_out_lp: mov ebx,esi
mov ecx,255
@@cmd_line_lp: cmp byte ptr [esi],0
jz @@end_cmd_line
cmp byte ptr [esi],32
jz @@got_cmd_line_str
inc esi
dec ecx
jnz @@cmd_line_lp
@@end_cmd_line: mov [done],1
@@got_cmd_line_str:
cmp ebx,esi
jz @@outy
lea edi,Args
add edi,argslen
mov eax,[arguments]
mov [eax * 4 + ArgumentList],edi
@@got_dest_str: mov al,[ebx]
inc ebx
inc [argslen]
stosb
cmp ebx,esi
jb @@got_dest_str
mov byte ptr [edi],0
inc [argslen]
inc esi
inc [arguments]
cmp [done],0
jz @@cmd_out_lp
@@outy: mov eax,arguments
ret
Break_Command_Line endp
;***********************************************************************************************
;* Parse_Command_Line -- Suck the goodness out of the command line *
;* *
;* *
;* INPUT: Nothing *
;* *
;* OUTPUT: Nothing *
;* *
;* Warning: None *
;* *
;* HISTORY: *
;* 10/29/2001 12:39PM ST : Created. *
;*=============================================================================================*
Parse_Command_Line proc C
local argnum:dword
local num_args:dword
local file_number:dword
call Break_Command_Line
cmp eax,1
jbe @@pcl_out
mov [num_args],eax
;
; Parse options first. Ignore the first argument - it's the path to the .exe
;
mov [argnum],1
@@pcl_opt_outer:
mov eax,[argnum]
cmp eax,[num_args]
jae @@pcl_out
mov esi,[eax*4 + ArgumentList]
mov al,[esi]
cmp al,'-'
jz @@pcl_option
cmp al,'/'
jnz @@pcl_get_file_list
@@pcl_option: mov al,[esi+1]
cmp al,'n'
jz @@pcl_port_number
cmp al,'N'
jz @@pcl_port_number
;
; Don't know this option
;
lea eax,UnrecognisedOption
call Print
inc [argnum]
jmp @@pcl_opt_outer
@@pcl_port_number:
lea eax,[esi+2]
call String_To_Int
mov [BuildNumber],eax
mov [BuildNumberSpecified],1
inc argnum
jmp @@pcl_opt_outer
;
; Copy the file names from the argument list.
;
@@pcl_get_file_list:
mov [file_number],0
@@pcl_get_file_outer_lp:
mov eax,[argnum]
cmp eax,[num_args]
jae @@pcl_out
mov esi,[eax*4 + ArgumentList]
mov edi,[file_number]
mov edi,[edi*4 + FileNameList]
@@pcl_copy_lp: lodsb
stosb
test al,al
jnz @@pcl_copy_lp
inc [file_number]
inc [argnum]
;
; Only looking for 2 file names.
;
cmp [file_number],2
jz @@pcl_out
jmp @@pcl_get_file_outer_lp
@@pcl_out: ret
Parse_Command_Line endp
;***********************************************************************************************
;* String_To_Int -- Convert a string to an int. atoi. *
;* *
;* *
;* INPUT: eax - ptr to string *
;* *
;* OUTPUT: eax - int *
;* *
;* Warning: None *
;* *
;* HISTORY: *
;* 10/29/2001 12:39PM ST : Created. *
;*=============================================================================================*
String_To_Int proc C
;
; Get the end of the string
;
mov esi,eax
or ecx,-1
mov edi,esi
xor al,al
repne scasb
dec edi
cmp ecx,-1
jz @@nolen
mov ecx,1
xor ebx,ebx
@@more_digits: xor eax,eax
dec edi
mov al,[edi]
sub al,'0'
imul eax,ecx
add ebx,eax
imul ecx,10
cmp edi,esi
ja @@more_digits
mov eax,ebx
ret
@@nolen: mov eax,0
ret
String_To_Int endp
ifdef cuts
;***********************************************************************************************
;* Parse_Command_Line -- Suck the goodness out of the command line *
;* *
;* *
;* INPUT: Nothing *
;* *
;* OUTPUT: Nothing *
;* *
;* Warning: None *
;* *
;* HISTORY: *
;* 10/29/2001 12:39PM ST : Created. *
;*=============================================================================================*
Parse_Command_Line proc C
local arguments:dword
local done:dword
mov [arguments],0
mov [done],0
;
; Get a pointer to the command line.
;
invoke GetCommandLine
mov esi,eax
;
; Command line ptr is esi
;
@@cmd_out_lp: mov ebx,esi
mov ecx,255
@@cmd_line_lp: cmp byte ptr [esi],0
jz @@end_cmd_line
cmp byte ptr [esi],32
jz @@got_cmd_line_str
inc esi
dec ecx
jnz @@cmd_line_lp
@@end_cmd_line: mov [done],1
@@got_cmd_line_str:
cmp ebx,esi
jz @@outy
mov edi,[arguments]
shl edi,2
mov edi,[edi + FileNameList]
@@got_dest_str: mov al,[ebx]
inc ebx
stosb
cmp ebx,esi
jnz @@got_dest_str
inc esi
inc [arguments]
cmp [arguments],3
jz @@outy
cmp [done],0
jz @@cmd_out_lp
@@outy: ret
Parse_Command_Line endp
endif
;***********************************************************************************************
; Jump table for routing API calls without using the mangled __imp names
;
;
OutputDebugString proc STDCALL ;proc STDCALL string:ptr byte
jmp [__imp__OutputDebugStringA@4]
OutputDebugString endp
GetStdHandle proc STDCALL ; handle_type:dword
jmp [__imp__GetStdHandle@4]
GetStdHandle endp
GetFileSize proc STDCALL ; handle:dword, file_size_high:ptr dword
jmp [__imp__GetFileSize@8]
GetFileSize endp
WriteConsole proc STDCALL ; handle:dword, string:ptr byte, numchars:dword, charswritten:ptr dword, reserved:ptr dword
jmp [__imp__WriteConsoleA@20]
WriteConsole endp
CreateFile proc STDCALL ; file_name:ptr byte, access_mode:dword, share_mode:dword, sec_attr:ptr byte, creation_disposition:dword, flags:dword, template:dword
jmp [__imp__CreateFileA@28]
CreateFile endp
CloseHandle proc STDCALL ; handle:dword
jmp [__imp__CloseHandle@4]
CloseHandle endp
HeapAlloc proc STDCALL ; handle:dword, flags:dword, bytes:dword
jmp [__imp__HeapAlloc@12]
HeapAlloc endp
HeapFree proc STDCALL ; handle:dword, flags:dword, memptr:ptr byte
jmp [__imp__HeapFree@12]
HeapFree endp
HeapCreate proc STDCALL ; flags:dword, startsize:dword, maxsize:dword
jmp [__imp__HeapCreate@12]
HeapCreate endp
HeapDestroy proc STDCALL ; handle:dword
jmp [__imp__HeapDestroy@4]
HeapDestroy endp
ReadFile proc STDCALL ; handle:dword, buffer:ptr byte, bytes_to_read:dword, bytes_read:ptr dword, overlapped:ptr byte
jmp [__imp__ReadFile@20]
ReadFile endp
WriteFile proc STDCALL ; handle:dword, buffer:ptr byte, bytes:dword, bytes_written:ptr dword, overlapped:ptr byte
jmp [__imp__WriteFile@20]
WriteFile endp
GetFileTime proc STDCALL ; handle:dword, create_time:ptr dword, access_time:ptr dword, write_time:ptr dword
jmp [__imp__GetFileTime@16]
GetFileTime endp
SetFileTime proc STDCALL ; handle:dword, create_time:ptr dword, access_time:ptr dword, write_time:ptr dword
jmp [__imp__SetFileTime@16]
SetFileTime endp
SetFilePointer proc STDCALL ; handle:dword, distance:dword, dist_high:ptr dword, method:dword
jmp [__imp__SetFilePointer@16]
SetFilePointer endp
FileTimeToLocalFileTime proc STDCALL ; utc_time:ptr dword, local_time:ptr dword
jmp [__imp__FileTimeToLocalFileTime@8]
FileTimeToLocalFileTime endp
GetUserName proc STDCALL ; buffer:ptr byte, buffer_len:ptr dword
jmp [__imp__GetUserNameA@8]
GetUserName endp
GetCommandLine proc STDCALL
jmp [__imp__GetCommandLineA@0]
GetCommandLine endp
_text ends
end