News:

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

How to change variables sent to the procedure ???

Started by Pawel Blaszczyk, March 05, 2006, 03:29:31 PM

Previous topic - Next topic

Pawel Blaszczyk

I have got the problem with my procedure. I want send to it pointer to the global variable (byte string). Then modify it somehow. And after end of the procedure I'd like to have its result in this variable. There are cut and pasted fragments of my simply program.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;     P r o c e d u r e  P r o t o t y p e s             ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;//

ModifyTxt          PROTO         :PTR BYTE
...
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;    D a t a ?  S e c t i o n                                ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;//

.DATA
Text          DB          255     dup(?)
....
invoke       ModifyTxt, OFFSET Text
...
ModifyTxt          PROC     USES EDX ECX,       Txt:        PTR BYTE

XOR   EDI,   EDI                              ;  Set EDX register to zero
   .WHILE   Txt[EDX] != 0                ; Edit text while current byte of text equal zero
      ADD   BYTE PTR Txt[EDX], CH   ;Add value from CH reg. to Txt at position in EDX
      INC   CH                      ; increase the adding value
      INC   EDX                   ; increase index
   .ENDW
   invoke MessageBox, Hwnd, ADDR Txt, 0, MB_OK          ; show results in message box
RET
ModifyTxt          ENDP

I fought it will work but 'Text' variable after this procedure is like it was before. Txt != Text :eek. (Text in MessageBox is OK)
I know how to do it in C++ or TPascal but in Assembler it is black magic[/glow]  :lol
Can somebody (who understand what I wrote) help me?

Light-I

#1
This my verson (masm32 of course) of your code, without flashing bulbs ;) :ModifyTxt PROTO :LPSTR

.data?
BuffTxtToChange db 255 dup(?)
...
.code
invoke ModifyTxt, ADDR BuffTxtToChange
invoke MessageBox, hWnd, ADDR BuffTxtToChange, NULL, MB_OK          ; show results in message box
...
ModifyTxt proc uses eax edi, lpTxt:LPSTR
mov ch, 0 ; clear high byte of ecx - bits from 8 to 15
mov edi, lpTxt
mov al, [edi]
.while al != 0
add al, ch
inc ch
stosb ; same as -> mov [edi], al + inc edi
.endw
ret
ModifyTxt endp
I hope I guess your idea... ;)

donkey

Hi all,

First,

CH is reserved, it is the second byte in ECX so unless you are just trying to make the code unreadable or obfuscate it, don't use CH. Didn't MASM spit out an error when you did that ?

Second,

XOR   EDI,   EDI                              ;  Set EDX register to zero

does not set the EDX register to 0, it sets the EDI register to 0, they are different.

Third,

in the example Txt resolves to an offset from EBP (or ESP depending on your assembler). You should move the value into a register and use that otherwise you are just writing to the stack not the original buffer. For example...

mov edi, Txt ; store the value in Txt in the EDI register
mov BYTE PTR [edi], 0 ; mov 0 into the first location of the offset passed in Txt

Edgar
"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

MichaelW

Pawel,

The value of the Txt parameter is set to the address of Text (00403000h) when the procedure is invoked. The MessageBox function expects an address in the lpText parameter, so this:

invoke MessageBox, Hwnd, ADDR Txt, 0, MB_OK

Should be:

invoke MessageBox, Hwnd, Txt, 0, MB_OK


It would be easier for you to see what is going on if you would initialize Text to something recognizable.

Text db 255 dup('X'),0

And code your procedure to modify it to something recognizable. For example, you could convert the above example string to lower case by adding the value 'x'-'X' to each character.


eschew obfuscation

Pawel Blaszczyk

Thanks Light-I and donkey.
At start I'm sorry for my mistake in source code I sent (I made mistakes during formatting it- adding colours etc).
It had to confuse you both. Following is version without colours.

ModifyTxt PROC USES EDX EAX, Txt: PtrBYTE
XOR     CX,     CX           ; to set register CX to 0
XOR EDI, EDI         ; EDI = 0
.WHILE Txt[EDI] != 0              ; 1.
ADD BYTE PTR Txt[EDI], CH        ; 2.
                INC CH                                      ; increase higher part of CX reg.
INC EDI                                     ; increase EDI
.ENDW
RET
ModifyTxt ENDP


1. I fought It work like: while address of proc. argument + EDI not equal 0. Now I am not sure :green.
2. Yes, I wanted it to adding value from CH (register) to place no. value_in_EDI in Txt (which in fact is byte string, which was sent to procedure).

Light-I your code (after I changed it to do work I wanted) changing argument of the procedure, but it also modify variable declared after this argument:
.data
Var1       db    255 dup(?)
Var2       db    10 dup(?)         ; when address of Var1 is the procedure's argument, procedure also modifies this variable
.... 
ModifyTxt proc uses eax edi, lpTxt:LPSTR
mov CH, 0
mov edi, lpTxt
mov al, [edi]
.while al != 0
        add al, CH
        inc CH
        stosb ; mov [edi], al + inc edi
.endw
ret
ModifyTxt endp


Again thanks. (I do not know how to describe it better. I learning English for not too long :toothy.)

.... wow! just before I clicked 'Post'.
Yes. You are right Mchael. I overlook that. I think it is because I am still scared about assembler (During I learned C++ I read a lot of things like: Assembler is to difficult to learn etc and now that are results of it....  But I do not going to give-up  :toothy)

Pawel Blaszczyk

I'm so embarassed. I wrote it wrong again :red. That is correct (in meaning, that is how my code looks, I didn't say it work correct):

ModifyTxt PROC USES EDI ECX, Txt: PtrBYTE

XOR EDI, EDI
.WHILE Txt[EDI] != 0
ADD BYTE PTR Txt[EDI], CH
INC CH
INC EDI
.ENDW
RET
ModifyTxt END


Yes... Sometimes I am a problem maker. FORGIVE ME PLEASE.

Pawel Blaszczyk

#6
Donkey I have got one more question for you. I change my code as you said in point no. 3. So it looks like follows:
ModifyTxt PROC USES ESI ECX EDI, Txt: PtrBYTE

XOR ESI, ESI
XOR ECX, ECX
MOV EDI,  Txt
CLoop:
cmp Txt[ESI], 0
JE CEnd
ADD BYTE PTR[EDI][ESI], CH
INC ESI
INC CH
CEnd:
RET
ModifyTxt ENDP

But I do not know why when I sending to this procedure address of argument which is 20 characters long, it do not stop when ESI = 20.
arg    db    "some text to change", 0
...
invoke ModiffyTxt, ADDR arg

What did I omit again?

donkey

I have no idea what you expect for a result but based on the code you submitted try this...

ModifyTxt PROC USES ECX EDI, Txt:DWORD

XOR ECX, ECX
MOV EDI,  Txt
CLoop:
         cmp BYTE PTR [EDI+ECX], 0
         JE CEnd
         ADD BYTE PTR [EDI+ECX], CH
         INC ECX
         JMP CLoop
CEnd:
RET
ModifyTxt ENDP


It won't actually change anything because CH is 0 for the first 256 characters which makes it kind of useless, just adds 0 to the character values in the string but that's essentially what yours does. Why not explain what you want to do to the string and we can probably help alot more.
"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

Pawel Blaszczyk

#8
Ok. So want I want to do is:
-   To have loop which is executing until some element of sent procedure's argument not equal zero.
-   In loop body I want change each element of the sent argument, by different value. It does not matter how (I want to change my 'About the program' information. So in .data section I going to put text that after procedure will make sense. I know it is a bit stupid method but at the start I think it is enough i.e.
If changing method taking away from each element of sent string, increased in each toe of the loop value, my variable will looks like that:
AboutTxt   DB   'P', 'R+1', 'O+2', 'G+3', 'R+4', 'A+5', 'M+6' ....
So it equal:
AboutTxt   DB    80,   83,       81,      74,       86,      70,       83   ...
And after calling procedure:
AboutTxt   DB    80,   32,       79,       71,       82,      65,       77 .....

It is just example. I know that better method would be XOR each text element by value increased by itself i.e.
XOR ECX, ECX
MOV     EAX,    2h
MOV EDI, Txt
...
ADD EAX, EAX
XOR BYTE PTR  [EDI+ECX], AH
INC ECX
...

but it is not the subject of this post.
Yes it is what I want exactly do. (I know, I know I should write it at start, but at start I had only problem because I was writing to stack not to sent parameter). I hope my English is good enough and you understand what I wrote. :lol
//I attached my whole source code (program is not finished), and program to creating data (so you don't have to calculate everythink yourself. It can save result to crrent directory to file 'DB Creator.txt'.)


[attachment deleted by admin]

AsmER

Hi Pawel,

I'm sorry that I can't help you with your problem, but I asked my Polish friend what he think about that and he said he know Web sites which should help you.
I speak polish a little bit and I think those websites should be good source of information about assembler for you.

http://www.republika.pl/skowi_magik/
http://www.shitsoft.net/programowanie/asm/index2.htm

I hope I helped - AsmER :U
PS
Cheers for that picture with dragon :8)

santa

Hellow,

I have no idea what you expect for a result as well, so if you can explain it in polish ..... :8)

Light-I

OK, maybe it helps you :ModifyTxt PROTO :LPSTR
...
.const
MAX_STRING_SIZE equ 145 ; especialy other value than 255 (0FFh)... ;)
.data?
BuffTxtToChange db MAX_STRING_SIZE dup(?)
.data
TxtToChange db "Our text to change", 0
.code
...
invoke lstrcpy, ADDR BuffTxtToChange, ADDR TxtToChange ; it's no so clear - modyfing in ".data" section, so copy it to ".data?"...
invoke ModifyTxt, ADDR BuffTxtToChange
invoke MessageBox, hWnd, ADDR BuffTxtToChange, NULL, MB_OK          ; show results in message box
...
....
.code
ModifyTxt proc uses eax ecx edi, lpTxt:LPSTR
mov ch, 0; may be xor ch, ch etc...
mov edi, lpTxt
mov al, [edi]
ModifyTxtLoop:
cmp al, 0 ; It's string end (usually strings in C are zero ended) ?
jnz @F ; if not - go on...
ret ; else return
@@:
add al, ch
stosb ; mov [edi], al + inc edi
inc ch
cmp ch, MAX_STRING_SIZE
jnz ModifyTxtLoop ; if ch not excide maximum, continue loop
ret
ModifyTxt endp

AsmER

Pawel,

I hope that it is what you wanted to do :lol:

ModifyTxt proc uses eax edi, lpTxt: LPSTR
MOV EDI, lpTxt
XOR EAX, EAX
MTLoop:
CMP BYTE PTR [EDI + EAX], 0h
JE MTLoopEND

ADD BYTE PTR [EDI + EAX], AL
INC EAX
JMP MTLoop
MTLoopEND:

RET
ModifyTxt ENDP


Regards, AsmER :U

Pawel Blaszczyk

Cheers everybody, you did it -  it work now :cheekygreen:.
I see I have a lot of work to do...
(thanks for patience)