News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

reading a string within a string

Started by white scorpion, January 13, 2005, 10:06:29 PM

Previous topic - Next topic

white scorpion

Hi All,

i'm trying to figure out a way to read a string within the string and then fill the new buffer with the characters behind the string.

explanation:

string1 db "this is the main string which <title> this is the title </title> needs to be used.
",0
buffer db 80 dup (?)


well, the thing i'm trying to achieve is getting the text between the <title> blocks into the buffer,
so that buffer = "this is the title"


i've tried it using the following code:

lea eax,string1
lea ebx,buffer
run:
cmp byte ptr [eax],'<'
inc eax
jne run
cmp byte ptr [eax],'T'
inc eax
jne run
cmp byte ptr [eax],'I'
inc eax
jne run
cmp byte ptr [eax],'T'
inc eax
jne run
cmp byte ptr [eax],'L'
inc eax
jne run
cmp byte ptr [eax],'E'
inc eax
jne run
cmp byte ptr [eax],'>'
inc eax
jne run
run2:
mov ecx,[eax]
mov [ebx],ecx
inc eax
cmp byte ptr [eax],'<'
jne run2
mov ecx,0
mov [eax],ecx


the above code was only meant for the first part, copying everything from after <title> to the buffer, but it won't start copying :(


any ideas would be highly appreciated ;)


donkey

Well, you have to scan ahead until you reach the point in the string you want, you can use an instr type function for that. I think there is one in MASM32. Once you know the point to start and the length to copy you can use lstrcpyn to copy a specific number of bytes or just rep movsb them. Here is an instr function in GoAsm syntax from my strings library...

lszInstr FRAME pString,pFind,StartChar
uses esi,edi,ebx
LOCAL len :D

invoke lszLen,[pFind]
push eax
invoke lszLen,[pString]
mov ebx,eax
pop edx
cmp edx,eax
jle >
mov eax,-1
ret
:

mov eax,[StartChar]
or eax,eax
jns >
mov eax,-1
ret
:

sub ebx,edx
inc edx
mov [len],ebx
mov ebx,[StartChar]
:
mov ecx,edx
mov eax,[pString]
lea edi,[eax+ebx]
mov esi,[pFind]
repe cmpsb
or ecx,ecx
jz >E1
inc ebx
cmp ebx,[len]
jbe <

xor eax,eax
dec eax
ret

E1:
mov eax,ebx
RET
ENDF


lszInstr:
Finds an instance of one string in another beginning at a supplied point
Parameters:
pString = Pointer to a null terminated string to search
pFind = Pointer to a null terminated string to find
StartChar = 0 based index of the character at which to begin the search
Returns the 0 based index where the string was found, -1 if not found
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

white scorpion

hi, thanks for replying,

i already found the macro @instr for masm32, but i couldn't figure out what i could do with the return value..
i will study this function and if i can't get it to work then i'm a afraid i will indeed have to do it manually by movsb and cmpsb.

thanks for your help ;)

donkey

Hi,

As far as I know @instr is a compile time only macro, I assumed you were looking for something run-time. I think there is an szInstr or something function in MASM32 that is a runtime function.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

white scorpion

well, i will show you what i'm trying to do:



.386
.model flat,stdcall
option casemap:none


;the include files needed for our program
;------------------------------------------------------
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\wsock32.inc

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\wsock32.lib

;the data section
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.data
wsadata WSADATA<>
sa sockaddr_in <>
err     db "Error, closing down.",0
wsaerr  db "unable to start wsa.",0
host    db "http://www.whatismyip.com",0
sendms  db "GET / HTTP/1.1",13,10,
           "Host: www.whatismyip.com",13,10,
           "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1",13,10,
           "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",13,10,
           "Accept-Language: en-us,en;q=0.5",13,10,
           "Accept-Encoding: gzip,deflate",13,10,
           "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7",13,10,13,10,0
recvbuf db 3000 dup (?)

;the uninitialized data section
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.data?

sock    dd ?

;the code section
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.code
start:

invoke WSAStartup,101h,addr wsadata
.if eax!=NULL
invoke StdOut,addr wsaerr
invoke ExitProcess,1
.endif
invoke socket,AF_INET,SOCK_STREAM,0
.if eax==INVALID_SOCKET
invoke StdOut,addr err
invoke WSACleanup
invoke ExitProcess,1
.endif
mov sock,eax

mov sa.sin_family,AF_INET
invoke htons,80
mov sa.sin_port,ax
invoke gethostbyname,addr host
mov eax,[eax+12]
mov eax,[eax]
mov eax,[eax]
mov sa.sin_addr,eax

invoke connect,sock,addr sa,sizeof sa
.if eax==SOCKET_ERROR
invoke StdOut,addr err
invoke WSACleanup
invoke ExitProcess,1
.endif

invoke send,sock,addr sendms,sizeof sendms,0
.if eax==0
invoke StdOut,addr err
invoke WSACleanup
invoke ExitProcess,1
.endif

invoke recv,sock,addr recvbuf,sizeof recvbuf,0
.if eax==SOCKET_ERROR or 0
invoke StdOut,addr err
invoke WSACleanup
invoke ExitProcess,1
.endif

invoke StdOut,addr recvbuf

invoke WSACleanup
invoke ExitProcess,0
end start


as you can see this program makes a connection to www.whatismyip.com, well since the ip is given in the title i want to extract the ip from the recvbuf.

i wrote this program since i needed a program to learn about sockets in asm, but while writing this program you can see i bumped up to the next problem....

MichaelW

Quick and dirty. See macros.asm to unravel the macros.

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    .486                       ; create 32 bit code
    .model flat, stdcall       ; 32 bit memory model
    option casemap :none       ; case sensitive

    include \masm32\include\windows.inc
    include \masm32\include\masm32.inc
    include \masm32\include\kernel32.inc

    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\kernel32.lib

    include \masm32\macros\macros.asm

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      string1 db "this is the main string which <title> this is the title </title> needs to be used.",0
      buffer  db 80 dup(0)
    .code
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    ; Char position for istring is a 1-based index.
    mov   ebx, istring(1, ADDR string1, chr$("<title>"))
    mov   edi, istring(ebx, ADDR string1, chr$("</title>"))
    ; Overwrite first char of 2nd search string with null.
    mov   BYTE PTR [string1+edi-1], 0
    add   ebx, OFFSET string1 + @SizeStr(<<title>>) - 1
    mov   eax, cat$(ADDR buffer, ebx)
    ; Restore first char of 2nd search string.
    mov   BYTE PTR [string1+edi-1], '<'

    print ADDR buffer
    mov   eax, input(13,10,13,10,"Press enter to exit...")
    exit
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start

eschew obfuscation

white scorpion

Thanks for your reply..

with the following code i still get some errors, but at least now i know what to look for :D



.386
.model flat,stdcall
option casemap:none


;the include files needed for our program
;------------------------------------------------------
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\wsock32.inc

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\wsock32.lib

;the data section
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.data
wsadata WSADATA<>
sa sockaddr_in <>
err     db "Error, closing down.",0
wsaerr  db "unable to start wsa.",0
host    db "http://www.whatismyip.com",0
sendms  db "GET / HTTP/1.1",13,10,
           "Host: www.whatismyip.com",13,10,
           "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1",13,10,
           "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",13,10,
           "Accept-Language: en-us,en;q=0.5",13,10,
           "Accept-Encoding: gzip,deflate",13,10,
           "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7",13,10,13,10,0
recvbuf db 3000 dup (?)
buffer  db 400 dup (?)

;the uninitialized data section
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.data?

sock    dd ?

;the code section
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.code
start:

invoke WSAStartup,101h,addr wsadata
.if eax!=NULL
invoke StdOut,addr wsaerr
invoke ExitProcess,1
.endif
invoke socket,AF_INET,SOCK_STREAM,0
.if eax==INVALID_SOCKET
invoke StdOut,addr err
invoke WSACleanup
invoke ExitProcess,1
.endif
mov sock,eax

mov sa.sin_family,AF_INET
invoke htons,80
mov sa.sin_port,ax
invoke gethostbyname,addr host
mov eax,[eax+12]
mov eax,[eax]
mov eax,[eax]
mov sa.sin_addr,eax

invoke connect,sock,addr sa,sizeof sa
.if eax==SOCKET_ERROR
invoke StdOut,addr err
invoke WSACleanup
invoke ExitProcess,1
.endif

invoke send,sock,addr sendms,sizeof sendms,0
.if eax==0
invoke StdOut,addr err
invoke WSACleanup
invoke ExitProcess,1
.endif

invoke recv,sock,addr recvbuf,sizeof recvbuf,0
.if eax==SOCKET_ERROR or 0
invoke StdOut,addr err
invoke WSACleanup
invoke ExitProcess,1
.endif

; Char position for istring is a 1-based index.
    mov   ebx, istring(1, addr recvbuf, chr$("<TITLE>"))
    mov   edi, istring(ebx, addr recvbuf, chr$("</TITLE>"))
    ; Overwrite first char of 2nd search string with null.
    mov   BYTE PTR [recvbuf+edi-1], 0
    add   ebx, OFFSET recvbuf + @SizeStr(<<TITLE>>) - 1
    mov   eax, cat$(addr buffer, ebx)
    ; Restore first char of 2nd search string.
    mov   BYTE PTR [recvbuf+edi-1], '<'
invoke StdOut,addr buffer

invoke WSACleanup
invoke ExitProcess,0
end start