News:

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

.REPEAT .BREAK .UNTIL

Started by ic2, March 06, 2008, 11:40:24 AM

Previous topic - Next topic

ic2

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]

Tedd

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.)
No snowflake in an avalanche feels responsible.

Jimg

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.

ic2

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...

Jimg

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?

ic2

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

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.

Jimg

#7
Deleted

Jimg

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.

ic2

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]

ic2

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], 4550h


Thank you again masm32 community


[attachment deleted by admin]

Jimg

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.

Rainstorm

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  ?

ic2

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 .WHILE
http://www.masm32.com/board/index.php?topic=8318.0

.CONTINUE used here with .REPEAT
http://www.masm32.com/board/index.php?topic=2942.0

Tedd

.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?
No snowflake in an avalanche feels responsible.