News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

jmp 3 bytes off

Started by jj2007, June 02, 2022, 10:59:36 AM

Previous topic - Next topic

jj2007

UASM v2.55, Mar 28 2022:

CASE WM_LBUTTONDOWN
push 1
call someproc
xor eax, eax
mov edx, 11111111h  ; marker for debugging
jmp OutHere
CASE WM_RBUTTONDOWN
push 0
call someproc
xor eax, eax
mov edx, 22222222h  ; marker for debugging
jmp OutHere
ENDSW

invoke CallWindowProc, opSubCanvas, hwnd, uMsg, wParam, lParam ; subclassing finished, continue with default handler
nops 2   ; 3 would be ok
OutHere: ret


Address   Hex dump          Command                                  Comments
00403623   .  33C0          xor eax, eax
00403625   .  BA 11111111   mov edx, 11111111                        ; first jump
0040362A   .  EB 2F         jmp short 0040365B                       ; wrong jump
0040362C   .  EB 17         jmp short 00403645
0040362E   >  3D 04020000   cmp eax, 204
00403633   .  75 10         jne short 00403645
00403635   .  6A 00         push 0                                   ; /Arg1 = 0
00403637   .  E8 73000000   call 004036AF
0040363C   .  33C0          xor eax, eax
0040363E   .  BA 22222222   mov edx, 22222222                        ; second jump
00403643   .  EB 16         jmp short 0040365B                       ; wrong jump
00403645   >  FF75 14       push dword ptr [ebp+14]                  ; /lParam
00403648   .  FF75 10       push dword ptr [ebp+10]                  ; |wParam
0040364B   .  FF75 0C       push dword ptr [ebp+0C]                  ; |Msg
0040364E   .  FF75 08       push dword ptr [ebp+8]                   ; |hWnd
00403651   .  FF35 84154100 push dword ptr [411584]                  ; |WinProc = ntdll.776F11A8
00403657   .  E8 82330000   call CallWindowProcA                     ; \USER32.CallWindowProcA
0040365C   .  90            nop
0040365D   .  90            nop
0040365E   .  5B            pop ebx
0040365F   .  5F            pop edi
00403660   .  5E            pop esi
00403661   .  C9            leave
00403662   .  C2 1000       retn 10


The problem ist the OutHere: ret

This works perfectly:

OutHere:
     ret

johnsa

Have you tried the same case here but not using the SWITCH/ENDSW ? - I'm wondering if the switch is causing the label to not be referenced correctly.

jj2007

#2
Quote from: johnsa on October 08, 2022, 06:40:48 AM
Have you tried the same case here but not using the SWITCH/ENDSW ? - I'm wondering if the switch is causing the label to not be referenced correctly.

Same for .if ... .else ... .endif chains. Unfortunately only for MasmBasic, which complicates the bug chasing a lot...
Note the bug does not raise its ugly head in ML and AsmC.

Load the attached exe into OllyDbg, run it with F9, then
- right-click into the edit control to see a correct jump (in SubCanvas)
- right-click into the main window's client area to see the buggy jump

The music plays here:
  CASE WM_LBUTTONDOWN ; **** the bug manifests itself here ****
nops 8 ; OxPT_Assembler mlv615 ; delete the x to activate ML
if 0
invoke MessageBox, 0, chr$("LButtondown"), chr$("Title"), MB_OK ; *** no bug ***
else
MsgBox 0, "LButtondown", "Hi", MB_OK ; **** bug ****
endif
xor eax, eax
mov edx, 11111111h ; marker for debugging
INT 3
jmp OutHere


... which translates to this:
004011F3   .  90            nop
004011F4   .  90            nop
004011F5   .  0FAE05 508640 fxsave [408650]
004011FC   .  51            push ecx
004011FD   .  6A 00         push 0                                   ; /Type = MB_OK|MB_DEFBUTTON1|MB_APPLMODAL
004011FF   .  68 9C704000   push offset 0040709C                     ; |Caption = "Hi"
00401204   .  68 A0704000   push offset 004070A0                     ; |Text = "LButtondown"
00401209   .  6A 00         push 0                                   ; |hOwner = NULL
0040120B   .  E8 9E000000   call <jmp.&user32.MessageBoxA>           ; \USER32.MessageBoxA
00401210   .  0FAE0D 508640 fxrstor [408650]
00401217   .  59            pop ecx
00401218   .  33C0          xor eax, eax
0040121A   .  BA 11111111   mov edx, 11111111
0040121F   .  CC            int3
00401220   .  EB 20         jmp short 00401242                       ; the bad jump


Most likely, the problem is triggered by the MsgBox macro:

MsgBox MACRO dlg:REQ, text:REQ, title:REQ, style:=<MB_OK or MB_SETFOREGROUND>
  MbXms   ; fxsave [408650]
  ifdif <dlg>, <0>
ifdif <dlg>, <NULL>
if @InStr(1, <dlg>, <h>) ne 1
echo
echo XXXX       MsgBox 0 or hWnd, "TEXT", "TITLE" [, MB_??]       XXXX
echo
.err
endif
endif
  endif
  push ecx
  push style
  push repargA(title)
  if mbx(text)
if mbx(title)
push -1
else
push 0
endif
call MbGetSlotPointer
push [edx]
  else
push repargA(text)
  endif
  push dlg
  call MessageBoxA
  MbXmr   ; fxrstor [408650]
  pop ecx
ENDM


For comparison, the original Masm32 SDK macro:
    MsgBox MACRO hndl,txtmsg,titlemsg,styl
      invoke MessageBox,hndl,reparg(txtmsg),reparg(titlemsg),styl
    ENDM

_japheth


Quote
The problem ist the OutHere: ret

Interesting bug.

I'm afraid you can't test with jwasm?

To catch the bug, it might be interesting to add another register to the "uses" clause.
Because the "3 bytes off" might be related to

  • the 3 registers that are "used"
  • a 5-byte jmp forward reduced to a 2 byte short jump by the assember in the 2. pass

Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

johnsa

The fact that it only breaks when the line contains both the label and the ret is interesting. This makes me wonder if it has something to do with the line queue, as "ret" is technically a macro.
Could you try using the retn 0x10 directly instead of ret ?

jj2007

Quote from: johnsa on October 19, 2022, 01:25:28 AMCould you try using the retn 0x10 directly instead of ret ?

Test attached:
  invoke DefWindowProc, hWnd, uMsg, wParam, lParam ; default processing
if 0
  OutHere:  pop ebx ; no crash
pop edi
pop esi
leave
retn 4*4
else
  OutHere:  ret    ; crash
endif
WndProc endp

johnsa

Thanks.. definitely sounds like some strange macro expansion artifact then coinciding with the branch destination shorting over passes..
Now to try make a very simple reproduction test-case.