Author Topic: TEXTEQU  (Read 12061 times)

hfheatherfox07

  • Member
  • ***
  • Posts: 464
Re: TEXTEQU
« Reply #15 on: September 03, 2012, 01:57:45 AM »
Frustrating..... :(

That why I mentioned that there is no tuts out there ....

I looked there and did not understand a thing ..... It takes me straight into ntdll

I commented out INT 3 and it works ....

Why did you ad a debugger trap? of course it will stop
If you comment out the ret after  MsgBox 0, arg1, arg2, MB_OK
than the program crashes after close

That is what I meant by a tut ....  a normal helloworld.exe that works and every thing commented in the disassem

Then a Helloworld.exe that crashes ....
And to show how to find that and why ....

For now I don't really need to know debug ...I will stay a way from it until I find a proper tut ...I am just going to get frustrated     :icon_cool:

Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

qWord

  • Member
  • *****
  • Posts: 1473
  • The base type of a type is the type itself
    • SmplMath macros
Re: TEXTEQU
« Reply #16 on: September 03, 2012, 03:14:30 AM »
That why I mentioned that there is no tuts out there ....
There are thousands of 'tutorials' whereas most of them are related to RE….

I commented out INT 3 and it works ....

Why did you ad a debugger trap? of course it will stop
It is a simple method to find the point of interest in your program - you can step over the INT3.

If you comment out the ret after  MsgBox 0, arg1, arg2, MB_OK
than the program crashes after close
What did you expect?

Then a Helloworld.exe that crashes ....
And to show how to find that and why ....
Olly stops at the instruction that cause the exception. The status bar shows what kind of exception occurs at this point. The problem for you is maybe that a crash can also occur in API functions - looking up the calling chain in the stack (-window) is useful in this case.
MREAL macros - when you need floating point arithmetic while assembling!

hfheatherfox07

  • Member
  • ***
  • Posts: 464
Re: TEXTEQU
« Reply #17 on: September 05, 2012, 04:14:47 AM »
Lets go back to this....
Originally this was posted :

Code: [Select]
_SignXorMask  TEXTEQU <[EBP-4]>  ;sign XOR mask
_OutLastDword TEXTEQU <[EBP-8]>  ;address of last dword in output buffer

what is a sign XOR mask?

Thank you
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

MichaelW

  • Global Moderator
  • Member
  • *****
  • Posts: 1209
Re: TEXTEQU
« Reply #18 on: September 05, 2012, 06:00:21 AM »
I don’t know what a sign XOR mask is, but _SignXorMask is a DWORD local variable.
Well Microsoft, here’s another nice mess you’ve gotten us into.

hfheatherfox07

  • Member
  • ***
  • Posts: 464
Re: TEXTEQU
« Reply #19 on: September 05, 2012, 07:36:17 AM »
Thanks...
But I ment what is "_SignXorMask" ?

So:

LOCAL  _SignXorMask: DWORD

What does that mean in an assembly ?
Like hdc  I thought SignXorMask was something specific
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

dedndave

  • Member
  • *****
  • Posts: 8823
  • Still using Abacus 2.0
    • DednDave
Re: TEXTEQU
« Reply #20 on: September 05, 2012, 09:32:13 AM »
don't get caught up on the wrong part of the story - lol

i only used those as examples - they are from a routine of mine that converts binary to decimal string
the names could be anything you like - meaningful to your specific code

in this case, the sign xor mask is a stored value that represents the binary sign of the input value
if the sign bit of the input value is 0 (positive), the value is initialized to 0 (dword)
if the sign bit of the input value is 1 (negative), the value is initialized to -1 (dword)
that mask is then used to XOR onto the dwords of the input value
at the end of conversion, the XOR mask is also added to the result
that way, the routine can handle positive or negative values the same way

(+1 xor 0) + 0 = +1
(-1 xor -1) + (-1) = -1

the routine is designed to handle signed or unsigned values, depending on a flag bit
so - if the flag bit is set - and the value is negative, the mask is set to -1
if the flag bit is not set - or the value is positive, the mask is set to 0

MichaelW

  • Global Moderator
  • Member
  • *****
  • Posts: 1209
Re: TEXTEQU
« Reply #21 on: September 05, 2012, 09:56:55 AM »
I did not have time to do much checking of this, so apologies for any errors.

This applies only to 32-bit code.

The stack is functionally a last in, first out (LIFO) data structure. The PUSH instruction subtracts 4 from the stack pointer (ESP) and then copies the contents of its operand (a 32-bit register or memory operand, or an immediate operand) to the stack at the address specified by ESP. The POP instruction copies the 32-bit value from the stack address specified by ESP to its operand (a 32-bit register or memory operand) and then adds 4 to ESP. As values are pushed, the stack “grows” down in memory. Barring direct manipulation of ESP it always points to the “top” of the stack, the location of the last item pushed and the next in line to be popped. Positive offsets from ESP point into the “active” stack space, and negative offsets into the “free” stack space.

The CALL instruction effectively pushes the return address (the address of the instruction following the CALL instruction) and then jumps to the address specified by its operand. The RET instruction effectively pops the value at the “top” of the stack and uses it as a jump destination.

The programmer can manipulate ESP indirectly using the CALL, RET, PUSH, and POP instructions as described above, or directly by using it as an instruction operand, typically for the ADD or SUB instructions. A key requirement here is that any adjustments to the address in ESP must preserve its 4-byte alignment, and this is normally accomplished by adding or subtracting some multiple of 4.

For both of the most common 32-bit calling conventions, STDCALL and CDECL, the procedure parameters are pushed (prior to the procedure call) in right to left order as they appear in the procedure definition or declaration. For STDCALL the called procedure is responsible for removing the parameters from the stack. This is normally done by appending a constant to the RET instruction that specifies the number of bytes to release, which will be 4 * the number of 32-bit parameters. For CDECL the caller is responsible for removing the parameters from the stack, so the procedure returns with a RET instruction with no constant appended.

Code: [Select]
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
.data
.code
;==============================================================================

;-----------------------------------------------------------------------------
; These options effectively turn off the automatically generated prologue and
; epilog code, so the only code in the procedure is the code that you see in
; the source.
;-----------------------------------------------------------------------------

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

Test1 proc arg1:DWORD, arg2:DWORD, arg3:DWORD, arg4:DWORD

    ;----------------------------------------------
    ; At entry the relevant contents of the stack
    ; expressed as offsets from ESP, are:
    ; [esp+16]  arg4
    ; [esp+12]  arg3
    ; [esp+8]   arg2
    ; [esp+4]   arg1
    ; [esp+0]   return address
    ;----------------------------------------------

    ;------------------------------------------------------
    ; Preserve EBP and set it to the current value of ESP,
    ; preparing it for use as a stack frame pointer.
    ;------------------------------------------------------

    push ebp
    mov ebp, esp

    ;---------------------------------------------
    ; At this point the relevant contents of the
    ; stack expressed as offsets from EBP, are:
    ; [ebp+20]  arg4
    ; [ebp+16]  arg3
    ; [ebp+12]  arg2
    ; [ebp+8]   arg1
    ; [ebp+4]   return address
    ; [ebp+0]   preserved EBP
    ;---------------------------------------------

    ;--------------------------------------------
    ; Reserve space on the stack for local data,
    ; in this case 4 dwords.
    ;--------------------------------------------

    sub esp, 16

    ;---------------------------------------------
    ; At this point the relevant contents of the
    ; stack expressed as offsets from EBP, are:
    ; [ebp+20]  arg4
    ; [ebp+16]  arg3
    ; [ebp+12]  arg2
    ; [ebp+8]   arg1
    ; [ebp+4]   return address
    ; [ebp+0]   preserved EBP
    ; [ebp-4]   local1
    ; [ebp-8]   local2
    ; [ebp-12]  local3
    ; [ebp-16]  local4
    ;---------------------------------------------

    _arg1 equ <DWORD PTR [ebp+8]>
    _arg2 equ <DWORD PTR [ebp+12]>
    _arg3 equ <DWORD PTR [ebp+16]>
    _arg4 equ <DWORD PTR [ebp+20]>

    local1 equ <DWORD PTR [ebp-4]>
    local2 equ <DWORD PTR [ebp-8]>
    local3 equ <DWORD PTR [ebp-12]>
    local4 equ <DWORD PTR [ebp-16]>

    mov eax, _arg1
    mov ebx, _arg2
    mov ecx, _arg3
    mov edx, _arg4

    mov local1, eax
    mov local2, ebx
    mov local3, ecx
    mov local4, edx

    printf("%d\t", local1)
    printf("%d\t", local2)
    printf("%d\t", local3)
    printf("%d\n\n", local4)

    ;-----------------------------------------------------------------
    ; Restore the entry-point value of ESP. This step is essential so
    ; the following POP and RET instructions will access the correct
    ; stack addresses.
    ;-----------------------------------------------------------------

    mov esp, ebp

    ;---------------------------------
    ; Recover the entry value of EBP.
    ;---------------------------------

    pop ebp

    ;---------------------------------------------------
    ; Return to the caller and adjust the stack pointer
    ; to remove the parameters (4 * 4 bytes each) from
    ; the stack, as per the stdcall calling convention.
    ;---------------------------------------------------

    ret 16

Test1 endp

;---------------------------------------------------------------
; Turn the default prologue and epilog code generation back on.
;---------------------------------------------------------------

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

;==============================================================================
start:
;==============================================================================

    push 4
    push 3
    push 2
    push 1
    call Test1

    inkey
    exit
;==============================================================================
end start
Well Microsoft, here’s another nice mess you’ve gotten us into.