News:

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

The official Kinky Kode thread

Started by Larry Hammick, December 09, 2007, 07:04:38 AM

Previous topic - Next topic

Larry Hammick

push 4C2h
call esp

It's a 7-byte NOP. I leave it to you to figure out how it works.

evlncrn8

executes from stack no?, and is a simple c2 04 00 00 (ret 4)...
not really usable in this day and age with dep, and so on.....

MichaelW

It’s not usable at all. I think what is happening is that pushing the return address for the call changes the value in ESP, so the call destination ends up being the location on the stack where the return address is stored, and the return address is not likely to be a workable instruction. This version will work:

push 4c2h
mov eax, esp
call eax

But a slow 9-byte nop that changes a register value is probably not too useful.
eschew obfuscation

Larry Hammick

#3
I didn't say it was useful :green but it shows that the stack is an executable segment under Windows, which is occasionally useful (a substitute for the hazardous practice of self-modifying code). The local heap is also executable.
Here are some faster NOP's:
db 8Dh,49h,0
db 66h,8Dh,49h,0
db 8Dh,89h,0,0,0,0

MichaelW makes a good point, that esp is ambiguous (or at least, looks ambiguous) in the instruction CALL ESP. In real life I use
    mov eax,esp
    push eax
instead of
    push esp
for the same reason. On the earliest Intel chips, after the instruction PUSH ESP, the value on the stack would be the NEW esp value, rather than the previous value, as it is on all the newer chips that I know of. To be safe, I never push esp directly.

update: The original PUSH 4C2h / CALL ESP does return properly, and the execution continues with no problem, at least on this Pentium 4.

MichaelW

It works fine on my P4, but on my P3 the CALL ESP is causing an exception because the destination address is the value of ESP after the return address is pushed.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
    include \masm32\include\debug.inc
    includelib \masm32\lib\debug.lib

    DBGWIN_EXT_INFO = 1
    DBGWIN_DEBUG_ON = 1
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
    .code
EH:
    ret
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    TrapException <offset EH>

    push 4c2h
    mov ebx, esp
    print "esp =            "
    print uhex$(ebx),13,10,13,10

    inkey "Press any key to continue..."
    print chr$(13,10)

    call ebx

    push 4c2h
    mov ebx, esp
    print "esp =            "
    print uhex$(ebx),13,10,13,10

    inkey "Press any key to continue..."
    print chr$(13,10)

    call esp

    inkey "OK"
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


esp =            0012FFB8

Press any key to continue...

esp =            0012FFB8

Press any key to continue...


=====================[EXCEPTION INFORMATION]====================
Exception code: EXCEPTION_ACCESS_VIOLATION
Location: , 0

eax=00000000 ebx=0012FFB8 ecx=0012FFBC edx=00000001 esi=00000000
edi=00000002 ebp=0012FFF0 esp=0012FFB4 eip=0012FFB5
CS=001B DS=0023 SS=0023 ES=0023 FS=0038 GS=0000  o d I S z a P c
----------------------------------------------------------------


I wonder if this change in behavior is documented somewhere.
eschew obfuscation

RuiLoureiro

MichaelW,
               Your code doesnt run on my P4 - Windows XP, SP2. Is there any reason ?

MichaelW

Quote from: RuiLoureiro on December 10, 2007, 04:52:34 PM
MichaelW,
               Your code doesnt run on my P4 - Windows XP, SP2. Is there any reason ?

I would guess the reason is DEP. What happens when you run it?

eschew obfuscation

RuiLoureiro


MichaelW

The attachment includes the source and the EXE.


[attachment deleted by admin]
eschew obfuscation

RuiLoureiro

Quote from: MichaelW on December 10, 2007, 06:21:59 PM
The attachment includes the source and the EXE.

When i saw your .asm i said: Console Assemble & Link.
It gives the same resulsts for ESP and at the end OK.

Have a nice night/day
Rui

Larry Hammick

Surprising that a P3 and a P4 differ in this way, but I don't blame Intel for not documenting such an obscure thing.

Here's another demo of (safer) code in the stack, using CPEEK, which is available here:
http://www.masm32.com/board/index.php?topic=8135.msg59649#msg59649
;Build file:
;\masm32\bin\ml /c /coff stack.asm
;\masm32\bin\polink /SUBSYSTEM:CONSOLE stack.obj

;;;;;;;;;;;;;;;; STACK.ASM:
.586
.model flat, stdcall
option casemap:none

.data
ExitAddress dd ?
.code

include cpeek.inc
@cpeek

Start:
pop ExitAddress
xor eax,eax
call regs         ;regs is a function in cpeek.dll
push 0E3FF40h   ;inc eax, jmp ebx
mov ebx,offset wherenext
jmp esp
wherenext:
add esp,4
call regs      ;observe that eax is now 1 and esp is the same as before
jmp ExitAddress
end Start

MazeGen

Quote from: MichaelW on December 10, 2007, 10:54:11 AM
I wonder if this change in behavior is documented somewhere.

It is actually a documented erratum (Specification Update 244460-004).

QuoteG15. Near CALL to ESP Creates Unexpected EIP Address

IMPLICATION: Due to this erratum, the processor may transfer control to an unintended address. Results are
unpredictable, depending on the particular application, and can range from no effect to the unexpected
termination of the application due to an exception. Intel has observed this erratum only in a focused testing
environment. Intel has not observed any commercially available operating system, application, or compiler that
makes use of or generates this instruction.

MichaelW

Quote from: MazeGen on December 11, 2007, 10:27:08 AM
It is actually a documented erratum (Specification Update 244460-004).

Thank you for finding this. The problem was apparently known in 1999, with no plans to fix it.
Quote
Problem: As documented, the CALL instruction saves procedure linking information in the procedure stack and jumps to the called procedure specified with the destination (target) operand. The target operand specifies the address of the first instruction in the called procedure. This operand can be an immediate value, a general purpose register, or a memory location. When accessing an absolute address indirectly using the stack pointer (ESP) as a base register, the base value used is the value in the ESP register before the instruction executes. However, when accessing an absolute address directly using ESP as the base register, the base value used is the value of ESP after the return value is pushed on the stack, not the value in the ESP register before the instruction executed.

eschew obfuscation

Larry Hammick

Time for some more Kinky Kode. Today we look at jumping to a nonexistent label.

;Build file:
;\masm32\bin\ml /c /coff phantom.asm
;\masm32\bin\polink /SUBSYSTEM:CONSOLE phantom.obj

;;;;;;;;;;;;;;;; PHANTOM.ASM:

.586
.model flat, stdcall
option casemap:none

include \masm32\include\kernel32.inc   ;only cpeek needs these.
includelib \masm32\lib\kernel32.lib

include cpeek.inc
@cpeek

.code

    db 66h    ;operand size override prefix
testlabel:
    inc eax
    call regs   ;Behold, ax but not eax has been incremented :D
    xor eax,eax
    jmp ebx      ;equivalent to ExitThread with return code in eax

Start:
    pop ebx
    mov eax,-1
    jmp testlabel-1

end Start

evlncrn8

hows it non existant then, its (offset) testlabel -1...
so you just jump to the db 66h....