Question

I have to code for a security project a shellcode. Just for training, I want to code a shellcode which open a very simple MessageBox. Here's below an extract of the whole code (this piece of code just call the 'LoadLibrary' and 'ExitProcess' function):

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc

.code

start:    
    jmp short GetLibrary

GetLibraryReturn:
    pop ecx                     ;recover 'user32.dllN'
    mov ebx, 758c4977h          ;recover LoadLibrary PTR
    push ecx                    ;push 'kernel.dll'
    call ebx                    ;invoke LoadLibrary

ender:
    push eax
    mov eax, 758c79b0h          ;ExitProcess
    call eax

GetLibrary:
    call GetLibraryReturn
    db 'user32.dll'
    db 00h

[...]

end start

As you can see, it's very simple. However as you can at the end of the code, there's the following instruction :

db 00h

Unfortunately, after compilation, I have an opcode '00' in the middle of the shellcode. To fix the problem there's a solution like this one :

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc

.code

start:    
    jmp short GetLibrary

GetLibraryReturn:
    pop ecx                     ;recover 'user32.dllN'
    xor edx, edx                ;init EDX register
    mov [ecx + 10], dl          ;replace 'N' by 'NULL'
    mov ebx, 758c4977h          ;recover LoadLibrary PTR
    push ecx                    ;push 'kernel.dll'
    call ebx                    ;invoke LoadLibrary

ender:
    push eax
    mov eax, 758c79b0h          ;ExitProcess addr
    call eax                    ;invoke 'ExitProcess'

GetLibrary:
    call GetLibraryReturn
    db 'user32.dllN'            ;Push an additional character 'N'

end start

So, the subtility is to add another character at the end of the 'user32.dll' original string. Next we just have to replace it by NULL initializing the edx register to 0 and executing the following instruction with the usage of a 8 bits register to replace the 'N' additional character :

mov [ecx + 10], dl    ;'10' corresponds to the 'user32.dll' string length

As you can see the two versions should execute the same thing. It's just the generated code which undergoes a modification. Unfortunately, the execution fails and I don't understand why. Maybe there is a keyword to add on the expression above. I tried severals combinations but the compilation failed. I'm really lost.

Thanks a lot in advance for your help.

Was it helpful?

Solution

A code segment is not writable, so if you define a string in the code segment you can not write to it, by default. You either have to declare it in the data segment, or you must modify the permissions of the code segment in order to be able to write to it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top