BinStrSearch

From NSIS Wiki
Jump to navigationJump to search

This function will find a text string in a binary file and returns the offset in the file. You push three parameters before calling it: the filename, the string to find, and the starting offset in the file. Then you call the function, and it returns with the offset of the start of the string left on the stack. If the file doesn't exist or the string was not found it puts a zero on the stack. The string search is case sensitive.

!include logiclib.nsh
 
Push 'C:\Program Files\NSIS\makensis.exe'
Push 'This program cannot be run in DOS mode.'
Push 0
Call BinStrSearch
Pop  $0    ; returns 78
 
Push 'C:\Program Files\NSIS\makensis.exe'
Push 'KERNEL32'
Push 320000
Call BinStrSearch
Pop  $0    ; returns 377268 (NSIS 2.25)
 
Function BinStrSearch
	Exch $R5	; BSS_Offset
	Exch 2
	Exch $R4	; BSS_Filename
	Exch
	Exch $R3	; BSS_String
	Push $0
	Push $1		; a string char
	Push $R0	; string length
	Push $R1	; a file char
	Push $R2	; file handle
	StrLen $R0 $R3
	${IfThen} $R0 = 0 ${|} Goto @errors ${|}
	FileOpen $R2 "$R4" r
 
	# find matching first char
	@loop_1st_char:
	StrCpy $1 $R3 1    ; string 1st_chr
	${Do}
		ClearErrors
		FileSeek $R2 $R5
		FileReadByte $R2 $R1
		${IfThen} ${Errors} ${|} Goto @errors ${|}
		IntOp $R5 $R5 + 1
		IntFmt $R1 "%c" $R1
	${LoopUntil} $1 == $R1
 
	# set string length, check rest of the string
	StrCpy $0 $R0
	${While} $0 > 1
		IntOp $0 $0 - 1
		StrCpy $1 $R3 1 -$0
		FileReadByte $R2 $R1
		IntFmt $R1 "%c" $R1
		${IfThen} $1 != $R1 ${|} Goto @loop_1st_char ${|}
	${EndWhile}
 
	# string matches!
	IntOp $R5 $R5 - 1
	Goto @done
 
@errors:
	StrCpy $R5 0
@done:
	FileClose $R2
	Pop $R2
	Pop $R1
	Pop $R0
	Pop $1
	Pop $0
	Pop $R3
	Pop $R4
	Exch $R5	; Return the offset
FunctionEnd

My apologies to the author whose work this was based upon. I can't find that article in the wiki to give credit to them.