:confused:
After a couple of hours of trying to figure out what was going wrong I noticed that the call was actualy calling a return directly???? And then lookg back through my code the previous call was calling two bytes before my proc, (however the "or al,0" and "nop" had no effect)

Werid?? Has anyone else ever noticed this:
Posted on 2002-09-18 03:46:45 by huh
Hey huh, ( :grin: )

another evidence that MASM is a sort of "high level" assembler. You don't have full control over your code :/
Maybe you should compile your code with FASM and compare the disassembled source :/
Posted on 2002-09-18 03:52:46 by bazik
I must recall you all that MASM is a Microsoft product. :grin:
Posted on 2002-09-18 08:11:07 by Maverick
Post your code: MASM is a Microsoft product, but there may be an error in the source... :)
Posted on 2002-09-18 08:43:38 by JCP
Ho ho...

I use NASM and have a copy of FASM handy for when I am ready to use it. MS products tend to be a bit too "feature rich" for my liking. ;)

From what I know of MASM it has quite a few constructs that may quietly modify the values of registers. A side effect of some directive/operator or the other could be causing you grief. The complication of MASM was one of the things keeping me away from win32 assembler. FASM and NASM are light weight tools that are relatively easy to learn. MASM is a beast with an encyclopedia of directives.

Anyway, enough MASM bashing. :p

Like someone else said, probably you are making a difficult-to-spot mistake. Another person might see it immediately though.
Posted on 2002-09-18 09:11:46 by Thanatos
huh,
just before the the "or al,0" and "nop" there is a "db C2" -- that looks a little out of place in the middle of your code. Maybe that has something to do with it? Hard to tell from such a little fragment...
--Chorus
Posted on 2002-09-18 09:31:27 by chorus
Here:

401123 C2 0C00 RETN 0C ;near return(16-bit disp)

next:

40136F C2
401370 0C00
||
40136F C2 0C00 RETN 0C ;the near return from a proc above(not visible in pic)

40136F C2
401370 0C
401371 00
401372 90

It LOOKS like your proc is off by +2. That does not explain why OllyDebug cant parse the C20C0090 above it.
Also, notice where the $ is at line 4013C2 vs line 401370. Perhaps that NOP before the stack frame is giving Olly a problem. Did you put that NOP there?

Edit: Read the post closer. Perhaps the NOP is causing a problem for MASM or LINK?
Posted on 2002-09-18 10:24:32 by ThoughtCriminal
are you using olly?
sometimes olly is doing problems (for me ) when you anlayze the code and scan for object file too
remove both of them and then anlayze again
Posted on 2002-09-18 10:26:20 by eko
I had almost same problem.Are you using CTEXT macro if so try to remove this macro and try it.With CTEXT, my code was jumping to wrong places.
Posted on 2002-09-18 11:57:40 by LaptoniC
LaptoniC, is correct. Due to a segment switch within the CTEXT macro MASM looses where it is in the code segment. Solution was found in this thread:
http://www.asmcommunity.net/board/index.php?topic=7797

Of course, we make many assumptions because no code was posted.
Posted on 2002-09-18 13:01:18 by bitRAKE
Sorry without having to paste all the source, I think the problem occours with this directive (and its use):

This is in an include file:


__cbFunctionA TYPEDEF PROTO cbFunctionA :DWORD,:DWORD,:DWORD
_cbFunctionA TYPEDEF PTR __cbFunctionA



Then my main code:


.CODE
include file1.asm
.
.
.
INVOKE FunctionA ,param,param ; $ = 00401114h


Then in "file1.asm":


cbFunctionA PROC param1:DWORD,param2:DWORD,param3:DWORD

ret
cbFunctionA ENDP ;$ = 0040136Fh


ALIGN 4
FunctionA PROC param1:DWORD,param2:DWORD ; $ = 00401373h

INVOKE FunctionB ,param1,param2,cbFunctionA,param3

ret
FunctionA ENDP



FunctionB PROC param1:DWORD,param2:DWORD,param3:DWORD,pram4:DWORD

mov edx,param3
INVOKE _cbFunctionA PTR edx ,param1,param2,param3

ret
FunctionB ENDP

Posted on 2002-09-18 18:49:31 by huh
I also noticed the dissambly of this function:


LogEvent PROC C USES ESI uMsgID:DWORD,params:VARARG
LOCAL StringBuffer[1024]:BYTE
LOCAL lvi:LVITEM

STRING nulstr," "


INVOKE GetStringFrmID ,ADDR EventStrings,uMsgID
.IF eax==-1
INVOKE wsprintf ,ADDR StringBuffer,CTXT("FATAL: Could not load string. (ID: %lu)"),uMsgID
INVOKE ProcessEvent ,uMsgID,ADDR StringBuffer,-1

xor eax,eax
.ELSE
lea esi,[eax + OFFSET EventStrings]
.IF ([STRING_HDR PTR [esi]].fString & ESTR_GAP)
mov lvi.imask,NULL
mov eax,numlogitems
mov lvi.iItem,eax
mov lvi.iSubItem,0
INVOKE SendMessage ,hwndLog,LVM_INSERTITEM,NULL,ADDR lvi

inc numlogitems
.ENDIF

.IF ([STRING_HDR PTR [esi]].fString & ESTR_PARAMS)
lea eax,params

INVOKE wvsprintf ,ADDR StringBuffer,ADDR [esi + SIZEOF STRING_HDR],ADDR params
INVOKE ProcessEvent ,uMsgID,ADDR StringBuffer,-1

.ELSE
lea eax,[esi + SIZEOF STRING_HDR]
INVOKE ProcessEvent ,uMsgID,eax,-1

.ENDIF

mov eax,TRUE
.ENDIF

ret
LogEvent ENDP


And its dissambly:


00401AF0 $ 55 PUSH EBP
00401AF1 . 8BEC MOV EBP,ESP
00401AF3 . 81C4 D8FBFFFF ADD ESP,-428
00401AF9 . 56 PUSH ESI
00401AFA . FF75 08 PUSH DWORD PTR SS:[EBP+8]
00401AFD . 68 DC204000 PUSH pecter.004020DC
00401B02 . E8 25010000 CALL pecter.00401C2C
00401B07 . 83F8 FF CMP EAX,-1
00401B0A . 75 25 JNZ SHORT pecter.00401B31
00401B0C . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; /<%lu>
00401B0F . 68 DD414000 PUSH pecter.004041DD ; |Format = "FATAL: Could not load string. (ID: %lu)"
00401B14 . 8D85 00FCFFFF LEA EAX,DWORD PTR SS:[EBP-400] ; |
00401B1A . 50 PUSH EAX ; |s
00401B1B . E8 08020000 CALL <JMP.&USER32.wsprintfA> ; \wsprintfA
00401B20 . 83C4 0C ADD ESP,0C
00401B23 . 6A FF PUSH -1
00401B25 . 8D85 00FCFFFF LEA EAX,DWORD PTR SS:[EBP-400]
00401B2B . 50 PUSH EAX
00401B2C . FF75 08 PUSH DWORD PTR SS:[EBP+8]
00401B2F E8 DB E8 ; <-------------------- Heres where it starts going wrong????
00401B30 . 95 XCHG EAX,EBP
00401B31 > 8DB0 00000000 LEA ESI,DWORD PTR DS:[EAX]
00401B37 . F746 04 100000>TEST DWORD PTR DS:[ESI+4],DC000010
00401B3E . 94 XCHG EAX,ESP
00401B3F .^7F C7 JG SHORT pecter.00401B08
00401B41 . 85D8 TEST EAX,EBX
00401B43 . FB STI
00401B44 FF DB FF
00401B45 FF DB FF
00401B46 00 DB 00
00401B47 00 DB 00
00401B48 00 DB 00
00401B49 . 00A1 0F304000 ADD BYTE PTR DS:[ECX+40300F],AH
00401B4F . 8985 DCFBFFFF MOV DWORD PTR SS:[EBP-424],EAX
00401B55 . C785 E0FBFFFF >MOV DWORD PTR SS:[EBP-420],0
00401B5F . 8D85 D8FBFFFF LEA EAX,DWORD PTR SS:[EBP-428]
00401B65 . 50 PUSH EAX ; /lParam
00401B66 . 6A 00 PUSH 0 ; |wParam = 0
00401B68 . 68 07100000 PUSH 1007 ; |Message = MSG(1007)
00401B6D . FF35 50324000 PUSH DWORD PTR DS:[403250] ; |hWnd = NULL
00401B73 . FF15 8C204000 CALL DWORD PTR DS:[<&USER32.SendMessageA>; \SendMessageA
00401B79 . FF05 0F304000 INC DWORD PTR DS:[40300F]
00401B7F . F746 04 080000>TEST DWORD PTR DS:[ESI+4],8
00401B86 . 74 2B JE SHORT pecter.00401BB3
00401B88 . 8D45 0C LEA EAX,DWORD PTR SS:[EBP+C]
00401B8B . 8D45 0C LEA EAX,DWORD PTR SS:[EBP+C]
00401B8E . 50 PUSH EAX ; /Arglist
00401B8F . 8D46 0C LEA EAX,DWORD PTR DS:[ESI+C] ; |
00401B92 . 50 PUSH EAX ; |Format
00401B93 . 8D85 00FCFFFF LEA EAX,DWORD PTR SS:[EBP-400] ; |
00401B99 . 50 PUSH EAX ; |s
00401B9A . FF15 A0204000 CALL DWORD PTR DS:[<&USER32.wvsprintfA>] ; \wvsprintfA
00401BA0 . 6A FF PUSH -1
00401BA2 . 8D85 00FCFFFF LEA EAX,DWORD PTR SS:[EBP-400]
00401BA8 . 50 PUSH EAX
00401BA9 . FF75 08 PUSH DWORD PTR SS:[EBP+8]
00401BAC . E8 18000000 CALL pecter.00401BC9
00401BB1 . EB 0E JMP SHORT pecter.00401BC1
00401BB3 > 8D46 0C LEA EAX,DWORD PTR DS:[ESI+C]
00401BB6 . 6A FF PUSH -1
00401BB8 . 50 PUSH EAX
00401BB9 . FF75 08 PUSH DWORD PTR SS:[EBP+8]
00401BBC . E8 08000000 CALL pecter.00401BC9
00401BC1 > B8 01000000 MOV EAX,1
00401BC6 . 5E POP ESI
00401BC7 . C9 LEAVE
00401BC8 . C3 RETN
Posted on 2002-09-19 00:29:33 by huh
Look at the thread I referenced above and note that you start the PROC with a macro: STRING. Also, you use the CTEXT macro - both need to be fixed, imho. Can you post the macros you are using?

Or just try adding:
... MACRO ...

LOCAL dummy
dummy EQU $
...
...
...
ENDM
...to each macro.
Posted on 2002-09-19 20:12:09 by bitRAKE
Instead of declaring procs like :


MyProc proc
....
ret
MyProc endp


Try :




MyProc:
...
retn XX
Posted on 2002-09-19 21:16:51 by Axial
BitRAKE cheers for your help,

Sorry, I did read that post, but I assumed the problem only occoured with the CTXT/CTEXT macro at the start of a proc and I forgot to remove the macros before I posted my previous post.

I have removed the macros, with equilivent code in the _DATA & _BSS sections, and everything compiles as it should.

Here are my macros anyway:


; --------------------------------
; initialised GLOBAL string value
; --------------------------------
STRING MACRO variable:REQ,args:VARARG
_DATA SEGMENT
variable BYTE args,0
_DATA ENDS
ENDM

; ---------------------
; literal string MACRO
; ---------------------
literal MACRO quoted_text:VARARG
LOCAL local_text
_DATA SEGMENT
local_text db quoted_text,0
_DATA ENDS
EXITM <local_text>
ENDM
; --------------------------------
; string address in INVOKE format
; --------------------------------
SADD MACRO quoted_text:VARARG
EXITM <ADDR literal(quoted_text)>
ENDM
; --------------------------------
; string OFFSET for manual coding
; --------------------------------
CTXT MACRO quoted_text:VARARG
EXITM <offset literal(quoted_text)>
ENDM


Cheers...
Posted on 2002-09-19 21:35:05 by huh
I was able to assemble your code with the following:
    ; --------------------------------

; initialised GLOBAL string value
; --------------------------------
STRING MACRO variable:REQ,args:VARARG
[b] LOCAL dummy
dummy EQU $[/b]
_DATA SEGMENT
variable BYTE args,0
_DATA ENDS
ENDM

; ---------------------
; literal string MACRO
; ---------------------
literal MACRO quoted_text:VARARG
LOCAL local_text
[b] LOCAL dummy
dummy EQU $[/b]
_DATA SEGMENT
local_text db quoted_text,0
_DATA ENDS
EXITM <local_text>
ENDM
; --------------------------------
; string address in INVOKE format
; --------------------------------
SADD MACRO quoted_text:VARARG
EXITM <ADDR literal(quoted_text)>
ENDM
; --------------------------------
; string OFFSET for manual coding
; --------------------------------
CTXT MACRO quoted_text:VARARG
EXITM <offset literal(quoted_text)>
ENDM


;########## dummy code/data to force assembly
;########## you won't need this ;)
STRING_HDR STRUCT
DWORD ?
fString DWORD ?
STRING_HDR ENDS

ESTR_GAP EQU 0DC000010h
ESTR_PARAMS EQU 8

GetStringFrmID PROC a:DWORD, b:DWORD
ret
GetStringFrmID ENDP

ProcessEvent PROC a:DWORD, b:DWORD, d:DWORD
ret
ProcessEvent ENDP

_DATA SEGMENT
hwndLog DWORD ?
EventStrings DWORD ?
numlogitems DWORD ?
_DATA ENDS
Many thanks goes to Maelstrom - he has solved a long standing problem with segment switches within macros. We will all profit from the continued ease of use in this style.

p.s. On a side note: there is never a need for SADD macro as OFFSET always works with a literal - unless you like the extra instruction and trash a register.

SADD EQU <CTXT> ;;)
Posted on 2002-09-20 00:00:58 by bitRAKE
Thanks for the mention bitRAKE :grin:

Glad to help.

Maelstrom
Posted on 2002-09-20 03:11:44 by Maelstrom