I been trying hard for days. I pick-up only a few new notes to get a idea of how to do it. I been thru my old thread below a hundred times and I tried everything I could think of. This is much difficult to understand than the WHILE & ENDWHILE with was tough also. Theres nothing much on the web about it other than here. That a long time searching. Now I went back to school to study Programming for knowledge and Networking for a job and i'm crazy about it too.
Could someone give me a out-line of what this code is doing so I can translate it to raw assembler.
Also I commented out parts of this code in the file below and it still works...but yOda coded it for a reason and I need to know why instead of just using this short cut... It still works but if it not needed I'll not use it. I guest by now every one know this has been my favorite example since when. What to do with this line is a trip:
UNTIL EAX == [edx+IMAGE_EXPORT_DIRECTORY.AddressOfNames] and the .BREAK directive is the monkey in the middle throwing me out loop and I can't take it no more.
Thank in advance
; repeatstart:
; cmp eax,1
; jne UNTIL_exitloop
; code goes here
; jmp repeatstart
; UNTIL_exitloop:
.REPEAT
MOV EDI, [EBX]
ADD EDI, dwDllBase
MOV ESI, [szApi] ; szApi
PUSH ECX ; save the api string length
REPZ CMPSB
.IF ZERO?
.BREAK
.ENDIF
POP ECX
ADD EBX, 4
INC EAX
.UNTIL EAX == [edx+IMAGE_EXPORT_DIRECTORY.AddressOfNames]
;; .REPEAT
;; .BREAK
;; .UNTIL EAX == IMAGE_EXPORT_DIRECTORY.AddressOfNames[edx]
More about other parts of this Macro and Tranlation:
http://www.masm32.com/board/index.php?PHPSESSID=40c7f25605407fc8f0b01e3bb9942e5c&topic=5915.0
[attachment deleted by admin]
If you understand .while/.endw then .repeat/.until shouldn't cause you any trouble - the only real difference is that repeat checks the condition at the end of the loop, but while checks it at the start. The result being that while may never enter the loop, but repeat must go through it at least once.
mov ecx,10
.repeat
dec ecx
.until ecx==0
As for .break -- in both .repeat and .while, it will jump out of the loop (from where execution will continue with the next instruction.)
You also need to move your pop up before the break, or you stack will not be correct. e.g.
.REPEAT
MOV EDI, [EBX]
ADD EDI, dwDllBase
MOV ESI, [szApi] ; szApi
PUSH ECX ; number of characters to compare. save the api string length for next time through loop
REPZ CMPSB ; look for difference between strings
POP ECX ; get back number of characters to check (and fix stack)
.BREAK .IF ZERO? ; quit if there was no difference
ADD EBX, 4
INC EAX
.UNTIL EAX == [edx+IMAGE_EXPORT_DIRECTORY.AddressOfNames]
I would make a lot of other changes myself, but this should fix the obvious.
Now I get it... I tried everything but what mess me up is trying to fixing this
.UNTIL EAX == [edx+IMAGE_EXPORT_DIRECTORY.AddressOfNames]
to maybe this
cmp eax, edx
jne _BACK_TO_REPEAT
I don't know...
Again, without passing judgment on if the code works or not-
MyLoop:
MOV EDI, [EBX]
ADD EDI, dwDllBase
MOV ESI, [szApi] ; szApi
PUSH ECX ; number of characters to compare. save the api string length for next time through loop
REPZ CMPSB ; look for difference between strings
POP ECX ; get back number of characters to check (and fix stack)
jz DoneLoop
ADD EBX, 4
INC EAX
cmp eax,[edx+IMAGE_EXPORT_DIRECTORY.AddressOfNames]
jne MyLoop
DoneLoop:
And if this still isn't what you are asking for, try again, I'll get it eventually.
Edit: apparently you modified your previous post while I was entering the answer. Still questions?
Jimg, I think I did that a few times but it did not work, then I went wild with all kinds of other ways.. I could have did something backwards but can't wait to get how to see.... I think this would not assemble for me. Should'n all the data be in EDX already.
cmp eax,[edx+IMAGE_EXPORT_DIRECTORY.AddressOfNames]
I can't wait to get home Thanks Jimg
IMAGE_EXPORT_DIRECTORY.AddressOfNames is a constant equal to the number of bytes from the start of the structure to the element AddressOfNames. Since edx doesn't change within the loop, it could be computed once before the start of the loop if that's what you want.
Deleted
You made somewhat a mess of the GetKernalBase routine also- should be something like this-
GetKernelBase PROC USES EDI ESI, dwTopStack : DWORD
MOV EDI, dwTopStack ; start the search
AND EDI, 0FFFF0000h ; wipe the LOWORD !
GKLoop:
.IF WORD PTR [EDI] == IMAGE_DOS_SIGNATURE
MOV ESI, EDI
ADD ESI, [ESI+03Ch]
cmp dword ptr [esi],IMAGE_NT_SIGNATURE
je DoneGK
.ENDIF
SUB EDI, 010000h
.IF EDI < MIN_KERNEL_SEARCH_BASE
MOV EDI, 0BFF70000h
.ENDIF
jmp GKLoop
DoneGK:
XCHG eax, EDI
RET
GetKernelBase ENDP
And I think there is a serious error in the way it is called. Nothing is pushed on the stack for the routine to use so it will pop one value off the stack before returning, which should seriously mess you up.
I see, you change (POP ecx) position by placing the BREAK equivalent code (jz DoneLoop) under it to get back number of characters to check (and fix stack). It worksing... I would have never thought to do that. I work in the order that an working example is presented. I posted yOda original code for others. I just spend my spare time every since trying to break it down to work for other assemblers such as POASM and FASM but lead to issues after issues to no-related issues.
POP ECX
jz DoneLoop
ADD EBX, 4
INC EAX
Thank you
PS:
QuoteYou made somewhat a mess of the GetKernalBase routine also- should be something like this-
Finally, so this is why my calls to the very first API under Visa overflows the buffer or something, and would never work. No other OS other than Visa detected that and ran my complete mess with-out a flaw. So it was'nt DEP fault in my case but it was my sloppy coding that caused errors. I used my version of yOda code in everything I done and none of them works under Visa.
QuoteAnd I think there is a serious error in the way it is called. Nothing is pushed on the stack for the routine to use so it will pop one value off the stack before returning, which should seriously mess you up.
That's right, It displayed a empty MessageBox when I call GetKernelBase. But when calling GetProcAddr with it it magically it returned a API that I see in the return MessageBox and the programs would still work. That always had me puzzled and keep me interested. Finally, my three year mistery solved. Who would ever guested other than a Pro.
QuoteNothing is pushed on the stack
I should go make an apology (somewhere) but I think I'll wait.
[/size]
Thanks again
[attachment deleted by admin]
QuoteAs for .break -- in both .repeat and .while, it will jump out of the loop (from where execution will continue with the next instruction.)
Ted I see what you mean... Take a look at the original code and the changed version. Note both GetKernelBase which use (WHILE).
Under (mov EDI, 0BFF70000h) (BREAK) is going back into the loop.
Under GetProcAddr which use (REPEAT) (BREAK) is use to jump out of the loop.:U :U :U
Now we ALL know for sure !!!I based my (WHILE) on donkey suggestion, and used Shantanu Gadgil, Dizz and others logic and Jimg put the icing on the cake for (REPEAT) ... It can be quite confusing but if anyone review this example the confusion will cease. Please check to make sure I label everything properly based on these conclusions. I think I got it right.
Bottom line (BREAK) can reverse depending. I will be looking at UNTIL a little harder just in case... and I like the Instruction... jnb _a_ENDWHILE making the next jump really a (BREAK) Instruction.
works great for MASM and POASM
need minor adjustments to work for FASM
not this ... cmp dword ptr [esi], 4550h
but this ... cmp dword[esi], 4550hThank you again masm32 community
[attachment deleted by admin]
You're still not getting it.
Your code:
;---- GET ImageBase of kernel32.dll ----
xor eax, eax
mov eax, esp ; PUSH dword ptr [ESP]
;PUSH [ESP]
CALL GetKernelBase
The "xor eax,eax" and "mov eax,esp" do absolutely nothing.
You commented out the push which put something on the stack for GetKernelBase to use so now the GetKernalBase proc will still screw up the stack when it closes out.
If you're not going to do the exception handler, you might as well remove any code having to do with SEH.
You've total removed this test:
.IF WORD PTR [EDI] == IMAGE_DOS_SIGNATURE
assuming it will always be true, which probably isn't the case.
I don't know what your intent was, but you took some well written code and generally made a mess of it. Now that you know more, start with the original and try again, you might learn something new.
ted wrote
QuoteAs for .break -- in both .repeat and .while, it will jump out of the loop (from where execution will continue with the next instruction.)
.break can be used only in
.while & .repeat loops nowhere else, is that right ? & same for
.continue ?
I want to take a crack at this question before I get confuse again.
Quote.As for .break -- in both .repeat and .while, it will jump out of the loop
This is what most were people was trying to tell me before at the other thread posted above and while googling... but I didn't get it. It was said in many difference ways and backwards.
Quote(from where execution will continue with the next instruction.)
Then this statement made it all so clean and final ... After experence in breaking .WHILE down in yOda code this may have proven otherwise... I figure it depends on how you use it and with what jcc to make it repeat or exit ...
Quote.break can be used only in .while & .repeat loops nowhere else, is that right ?
WHILE / REPEAT is what .break was design for. I bet .continue was a stand-along. Doing my search for the past few weeks I can almost swear that I saw it in few places where .BREAK and .CONTINUE was used as
STAND-ALONG code. And if that was the case, it prove they can only be used to (
jump out of any loop design )... But when used with REPEAT or WHILE it can do a lot more. Unlike .CONTINUE I think .BREAK has special design (maybe even un-documented) features to jump
IN or OUT a loop.[/size]
I'm not really sure yet but i'm going to learn. These links may help..CONTINUE used a lot here with .WHILEhttp://www.masm32.com/board/index.php?topic=8318.0
.CONTINUE used here with .REPEAThttp://www.masm32.com/board/index.php?topic=2942.0
.break will jump to the end of the loop (either .while or .repeat) it is inside.
.continue jumps to the start of its loop.
There could be the possibility to use it for other looping constructs, but as far a I know masm only support these two.
It doesn't make sense to use break/continue outside of a loop - where would they jump to? what is the start/end?
I really don't intend to muddy the waters here, but technically and semantically,
.break jumps out of the loop (either .while or .repeat) it is inside, just past the .until or .endw.
.continue jumps to the part of the loop where it checks for the terminating condition.
what is this code from the masm hlp doing exactly with .break .if or should the .endw statement be right at the bottom
EXAMPLE
mov eax, 100
.while eax > 0
sub eax, 1
.endw
msgloop:
invoke GetMessage, ADDR msg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage, ADDR msg
invoke DispatchMessage,ADDR msg
jmp msgloop
I don't know what that mess is ::)
The normal message loop would be:
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (eax == 0)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
Which translates to:
@while:
invoke GetMessage, ADDR msg,NULL,0,0
test eax,eax
jz @out
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp @while
@out:
Tedd, thanks for clearing that & the code examples.
just one more question... : ) can the masm .break be used in an masm switch block ?
in the win SDK there is this example
case WM_CONTEXTMENU:
if (!OnContextMenu(hwnd, GET_X_LPARAM(lParam),
GET_Y_LPARAM(lParam)))
return DefWindowProc(hwnd, uMsg, wParam, lParam);
break;
why is the break after the return there ? what sense does that make ?
Made a quick test with Olly:
nop
.WHILE TRUE
dec eax
.BREAK .IF (eax == 0)
.ENDW
nop
.WHILE 1
dec eax
.BREAK .IF (eax == 0)
.ENDW
nop
.REPEAT
dec eax
.BREAK .IF (eax == 0)
.UNTIL 0
nop
.REPEAT
dec eax
.BREAK .IF (eax == 0)
.UNTIL FALSE
nop
... translates to ...
00403FFE 90 NOP
00403FFF > 48 DEC EAX
00404000 . 0BC0 OR EAX,EAX
00404002 . 74 02 JE SHORT ReTest.00404006
00404004 .^EB F9 JMP SHORT ReTest.00403FFF
00404006 > 90 NOP
00404007 > 48 DEC EAX
00404008 . 0BC0 OR EAX,EAX
0040400A . 74 02 JE SHORT ReTest.0040400E
0040400C .^EB F9 JMP SHORT ReTest.00404007
0040400E > 90 NOP
0040400F > 48 DEC EAX
00404010 . 0BC0 OR EAX,EAX
00404012 . 74 02 JE SHORT ReTest.00404016
00404014 .^EB F9 JMP SHORT ReTest.0040400F
00404016 > 90 NOP
00404017 > 48 DEC EAX
00404018 . 0BC0 OR EAX,EAX
0040401A . 74 02 JE SHORT ReTest.0040401E
0040401C .^EB F9 JMP SHORT ReTest.00404017
0040401E > 90 NOP
Masm doesn't care whether you use .while TRUE or .while 1, and produces exactly the same code for the equivalent .rep until true... clever :thumbu
Quote from: Rainstorm on March 08, 2008, 08:41:30 PM
just one more question... : ) can the masm .break be used in an masm switch block ?
nope - Masm chokes
Quote
in the win SDK there is this example
case WM_CONTEXTMENU:
if (!OnContextMenu(hwnd, GET_X_LPARAM(lParam),
GET_Y_LPARAM(lParam)))
return DefWindowProc(hwnd, uMsg, wParam, lParam);
break;
why is the break after the return there ? what sense does that make ?
It doesn't make any sense, but certain C dialects allow "falling through". Shiver :tdown
QuoteIt doesn't make any sense, but certain C dialects allow "falling through". Shiver ThumbsDown
l o l ! at the *shiver*....masm is the only language I've ever looked at & am trying to learn, so don't know anything about
Cmany thanks for clearing that up.
Apparently Java is also affected by that:
Common sense would indicate that after executing the instructions following a case statement, and having come across another case statement the compiler would then finish falling through the switch statement. However, for reasons best known to the designers of the language case statements only stop falling through when they come across a break statement.
http://www.jchq.net/tutorial/02_01Tut.htm
The designers of Java and C also had the bright idea that a ";" must tell their compilers that a linefeed will soon follow, and that flow control must be controlled by many many "{" and "}" characters. Try a Google search on "C programming" "repetitive stress injury" :wink
Quote from: jj2007 on March 09, 2008, 09:37:51 AM
Apparently Java is also affected by that:
Common sense would indicate that after executing the instructions following a case statement, and having come across another case statement the compiler would then finish falling through the switch statement. However, for reasons best known to the designers of the language case statements only stop falling through when they come across a break statement.
And I have seen many modern software that DOES use this feature (falling through the switch statement). For some desperate mental reason they do consider it "cool" and an acceptable programming practice. Also there are many programmers out there that consider that the more complicated and more special features of the compiler they use and the more obfuscated the code is ... the more intelligent they are.
It is also related to not loosing your job. If it take a long time for a new employee to understand your code (and the code is perfectly valid) they your job is "more safe".
Quote
The designers of Java and C also had the bright idea that a ";" must tell their compilers that a linefeed will soon follow, and that flow control must be controlled by many many "{" and "}" characters. Try a Google search on "C programming" "repetitive stress injury" :wink
That way it is more easy for the parser ... :D
Rainstorm:
Maybe you should take a look at other programming languages also. Of course there is no thing like ASM but a good programmer should also know C and a few other programming languages. At least in order to be able to read code that demonstrates some algorithms.
Quote from: Rainstorm on March 08, 2008, 08:41:30 PM
just one more question... : ) can the masm .break be used in an masm switch block ?
in the win SDK there is this example
case WM_CONTEXTMENU:
if (!OnContextMenu(hwnd, GET_X_LPARAM(lParam),
GET_Y_LPARAM(lParam)))
return DefWindowProc(hwnd, uMsg, wParam, lParam);
break;
why is the break after the return there ? what sense does that make ?
The masm 'switch' block is really just a macro that rewrites to an .if block; a compiled switch statement can be more complicated. Since there was no 'break' included with that macro set, it won't work (because it's really just inside an if, but then, it's not required either.)
The win sdk examples are mainly in C++, and standard C requires a break to end the current 'case' -- making it jump to the end of the switch statement (after all of the other 'cases.') C++ and Java copied the fall-through format mainly for compatibility (execution 'falls' into the next case's code unless there is a break to stop that.)
In that example, the break comes 'after' return because the return is actually inside the if (i.e. if true: return, else break.)
Quote
In the win SDK there is this example
Code:
case WM_CONTEXTMENU:
if ( !OnContextMenu(hwnd, GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)) )
{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
break;
why is the break after the return there ? what sense does that make ?
For C/C++ it makes perfect sense. That is because the return statement will be executed only if the if condition is true. Since there is no else statement then the code might still fall through on some situations. Hence the break statement is required unless the original programmer intended a fall through and in this case I do not think he did.
ted, thx ..... that explaination was really helpfull.
bogdan, yes.. maybe i'll try a high level language sometime. - at the moment am just trying to learn asm & in the process, reading & trying out stuff in the windows SDK that is quite vast & time consuming. - I've not so much as looked at any other language before starting out with asm- I usually kinda get the logic of the code examples in the sdk broadly speaking , ..in order to duplicate the functionality in asm, but not everything as i don't know the syntax.
..appreciate the help all.
Rainstorm
-