Machine Instructions Direct Execution Help?

AceInfinity

Emeritus, Contributor
Joined
Feb 21, 2012
Posts
1,728
Location
Canada
Anybody know what is wrong with this uncompiled byte code:
Code:
\xB8\xAF\x31\x45\x76\x68\xE8\x03\x00\x00\x68\xEE\x02\x00\x00\xFF\xD0

It's just not working the way I'd hoped. I am using Win8 x64 with Media Center, and I'm trying to call the Beep function from kernel32.dll.

:banghead:
 
Last edited:
Re: Shellcode Help?

Code:
Beep(700, 1000);

Code:
000007D0  68E803            push word 0x3e8
000007D3  0000              add [bx+si],al
000007D5  68BC02            push word 0x2bc
000007D8  0000              add [bx+si],al
000007DA  FF15              call word [di]

So here's what part of the relevent disassembly looked like from ndisasm... You can see the value for the second param of the Beep function from kernel32.dll being pushed onto the stack (0x3E8 = 1000, for a 1 second duration or 1000ms), as well as the frequency (0x2BC = 700).

I wrote my own C++ program that got the address of the Beep function from kernel32.dll which returned 0x764531AF, which I suspected was \xAF\x31\x45\x76 in shellcode.

Code:
GetProcAddress(
	GetModuleHandle(L"kernel32.dll"), 
	"Beep"
);

After doing some tests I could not get a beep, so I wondered if this was all accurate information, and it seemed to be confirmed after I did some other tests to get the address for this function.

I'm using Windows 8 x64 Pro with Media Center. Tested through VS to try some inline asm:

Code:
01258365          mov         eax,dword ptr ds:[012612B4h]
0125836A          push        3E8h
0125836F          push        2EEh
01258374          call        eax

This worked when ran directly in the debugger... Although this is not what I wanted, as that is not a usable address, if I was to convert this to shellcode:

Code:
dword ptr ds:[012612B4h]

So I tried substituting the actual function address from the kernel32.dll module as 0x764531AF (\xAF\x31\x45\x76) just to see, and no luck still even with putting that address in manually:
Code:
009163DA          mov         eax,764531AFh  
009163DF          push        3E8h  
009163E4          push        2EEh  
009163E9          call        eax

*Which became this in shellcode:
Code:
\xB8\xAF\x31\x45\x76\x68\xE8\x03\x00\x00\x68\xEE\x02\x00\x00\xFF\xD0

edit: NOTE: The inline asm worked for that address. But the shellcode derived from the disassembly did not... Just to clarify.

I tried anyways, because obviously the shellcode below as an example, was designed for XP SP3, and thus wouldn't work with my Win8 OS as shellcode is usually very OS dependent.

- XP SP3 Beep Function:
Code:
\x33\xC0\xB8 ... \x68\x00\x04\x00\x00\x68\x00\x03\x00\x00\xFF\xD0

Where the ... would indicate where the shellcode for the address to the function should be placed.

edit: Ahh.. This is annoying me, lol. I am determined to figure this out.

Even tried adding \x33\xC0 to the beginning (instruction XOR EDX,EDX) to set EDX register to 0, but it did not work. I'm currently trying to set up XP in Hyper-V to do some testing there...

edit: In the meantime, I'm going to try testing on XP and Windows 7 to see what I can get to work. If anyone wants to try some inline asm in C++ here is the code I came up with for the Beep function from kernel32.dll... I will post variations.

You can pass a hardcoded value as the address to the function:
Code:
__asm
{
	mov eax,dword ptr 0x764531AF // Kernel32.dll!76468543()
	push 0x3E8                   // Duration argument
	push 0x2EE                   // Frequency argument
	call eax                     // Call function
}

You can pass the address from the GetProcAddress() function:
Code:
PROC handle = GetProcAddress(
	GetModuleHandle(L"kernel32.dll"), 
	"Beep"
	);
cout << "Kernel32.dll Beep Func Address - 0x" << handle << endl;
__asm
{
	mov eax,handle
	push 0x3E8
	push 0x2EE
	call eax
}

Or put the function itself in directly to move the address into the EAX register:
Code:
__asm
{
	mov eax,Beep
	push 0x3E8
	push 0x2EE
	call eax
}

Keep in mind LIFO for the push instruction if you are wondering why it is reversed.

This was handy though, grabbing the address of a function, so I created a wrapper application for it in C using Code::Blocks.

edit: I was actually fooling around lots with inline asm in C++ for the last while, and it seems I am catching on quickly. ASM is actually a fairly simple language, if you know the rules. Here was my testing for bitshifting:

Code:
// 1
int x = 2;
__asm
{
	mov eax,x
	shr eax,2
	mov x,eax
}
cout << x << endl;

// 2
int y = 2;
y >>= 2;
cout << y << endl;

Marked by the comments, // 1 and // 2 are the exact same thing really. Just thought I would share my examples. Bitshifting to the right by 2, from 2, gives 0. (And that's what this demonstrates.)
 
Last edited:
Re: Shellcode Help?

Alright, nobody posted it appears lol, but I fixed it! And to add to the trouble, my shellcode was actually right the whole time. You have no idea how much time I put into trying to figure out why it wouldn't work though.

I also, had to add a ret though to avoid a segmentation fault however, when running my own shellcode.
 
I have also changed the title of the thread as it's a bit misleading. I'm actually just trying to execute direct byte code to learn more about ASM. I may post an example later.

TJs5njY.png


:beerchug2:
 
Last edited:
Sorry, Ace... I would have replied, but this is all Greek to me... :lol: I prefer to NOT attempt to communicate from my posterior!

I do like to read your threads though... even though I do not fully (or sometimes partially) understand them... I find them interesting!
 
Ahh, well here is an example in action for what I have been working on:


I also just increased the buffer size as the placeholder for the argumentative shellcode to 1024*10 bytes, so that is the max amount of bytes that you should expect to execute at runtime currently.

I am trying to figure out x86 vs x64 architecture when it comes to byte code, as debugging my program when attempting to run the shellcode below which should open notepad.exe does not work on my x64 edition of Windows 8 Pro; it was designed for x86:

\xFC\x48\x83\xE4\xF0\xE8\xC0\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xD2\x65\x48\x8B\x52\x60\x48\x8B\x52\x18\x48\x8B\x52\x20\x48\x8B\x72\x50\x48\x0F\xB7\x4A\x4A\x4D\x31\xC9\x48\x31\xC0\xAC\x3C\x61\x7C\x02\x2C\x20\x41\xC1\xC9\x0D\x41\x01\xC1\xE2\xED\x52\x41\x51\x48\x8B\x52\x20\x8B\x42\x3C\x48\x01\xD0\x8B\x80\x88\x00\x00\x00\x48\x85\xC0\x74\x67\x48\x01\xD0\x50\x8B\x48\x18\x44\x8B\x40\x20\x49\x01\xD0\xE3\x56\x48\xFF\xC9\x41\x8B\x34\x88\x48\x01\xD6\x4D\x31\xC9\x48\x31\xC0\xAC\x41\xC1\xC9\x0D\x41\x01\xC1\x38\xE0\x75\xF1\x4C\x03\x4C\x24\x08\x45\x39\xD1\x75\xD8\x58\x44\x8B\x40\x24\x49\x01\xD0\x66\x41\x8B\x0C\x48\x44\x8B\x40\x1C\x49\x01\xD0\x41\x8B\x04\x88\x48\x01\xD0\x41\x58\x41\x58\x5E\x59\x5A\x41\x58\x41\x59\x41\x5A\x48\x83\xEC\x20\x41\x52\xFF\xE0\x58\x41\x59\x5A\x48\x8B\x12\xE9\x57\xFF\xFF\xFF\x5D\x48\xBA\x01\x00\x00\x00\x00\x00\x00\x00\x48\x8D\x8D\x01\x01\x00\x00\x41\xBA\x31\x8B\x6F\x87\xFF\xD5\xBB\xF0\xB5\xA2\x56\x41\xBA\xA6\x95\xBD\x9D\xFF\xD5\x48\x83\xC4\x28\x3C\x06\x7C\x0A\x80\xFB\xE0\x75\x05\xBB\x47\x13\x72\x6F\x6A\x00\x59\x41\x89\xDA\xFF\xD5\x6E\x6F\x74\x65\x70\x61\x64\x00

... And points to 0x0028D71A as the problem:
Code:
[PLAIN]0028D716  xor         edx,edx  
0028D718  dec         eax  
0028D71A  mov         edx,dword ptr [edx+60h][/PLAIN]

The exception thrown when debugging:
Code:
0xC0000005: Access violation reading location 0x00000060.

So after EAX gets set to 0x00000000, the dec instruction subtracts one from the destination operand being the EAX register... Reading about the dec instruction, it treats all integers as unsigned datatypes too, which makes sense, being that the instruction is to subtract from the value.

This was just the result of being able to compile and run shellcode directly from a string of bytes for experimental purpose. This I compiled as a program written in C using Code::Blocks. I was fooling around with some various stuff in C++ earlier. I plan on seeing what I can do for pumping a set of byte instructions into a dummy program via C# just for the fun of it and learning later on... However, in the meantime, this is a POC, and is by no means "finished" yet as far as I am concerned...

I want to dynamically create a child process to run the shellcode in instead of having it run in the main parent process as the host for execution, or maybe even a dummy thread using the CreateThread or CreateRemoteThread functions. Same thing can be achieved using VirtualAlloc and CallWindowProc...

:beerchug2:
 
Last edited:
For those of you asking or wondering, I already got this fixed since yesterday. :beerchug2: I'm just looking to test different shellcode now and extend this further..
 
I updated GetProcAddr so that it will tell you what the shellcode for the address should be as well btw:

lCn0QVF.png


You can download the program in the attachment below if you want:
 

Attachments

I'm also following, slowly. :grin1:

I've never done anything like that before, but it looks interesting.
 
I'm also following, slowly. :grin1:

I've never done anything like that before, but it looks interesting.

If you don't have any idea of what this is for or what it is about, and perhaps many others do, this is a very essential part of learning programming at a very low level, but is also crucial to code security. There are many malicious things hackers can do with the kind of stuff I have posted above if your compiled program is vulnerable, such as buffer overflow exploitation, among many other things. There are many "programmers" out there that can write code, but the good ones (the good programmers), and of which are few and far between, realize these things and are able to interpret them well enough for prevention. And that is the whole reason for why I took on this challenge to understand all of the above, although I felt it was necessary to share some of the information with the communities I am a part of as well.

If you are a C programmer (especially!!), you'd better know this stuff as far as I can say lol. :lol:

NOTE: Other languages do apply, but lots of (bad) C programmers are guilty of making mistakes associated with what I have shown in this thread.
 
Last edited:
I'm still learning, give me time. :lol:

About code security, why is it so important for a C/C++ app or something similar? Does it only apply to online apps? If I write PHP code and there is a vulnerability, it could obviously be a major issue and allow a hacker to gain from the vulnerability. If I write a C++ application, that doesn't interact with the internet, what difference does it make if there is a buffer overflow exploitation? If it's an offline app that has been designed to solve a particular problem, and someone manages to exploit it so it doesn't work as intended - does anyone lose out? Does a hacker gain anything that way? E.g. if someone exploits AutoBlue - what could they do that would inconvenience anyone other than themselves?

I'm sure there are plenty of reasons, the major issue I can think of would probably be cracking software/allowing games to run without a disc etc, but is code security as important for offline apps?
 
I'm still learning, give me time. :lol:

About code security, why is it so important for a C/C++ app or something similar? Does it only apply to online apps? If I write PHP code and there is a vulnerability, it could obviously be a major issue and allow a hacker to gain from the vulnerability. If I write a C++ application, that doesn't interact with the internet, what difference does it make if there is a buffer overflow exploitation? If it's an offline app that has been designed to solve a particular problem, and someone manages to exploit it so it doesn't work as intended - does anyone lose out? Does a hacker gain anything that way? E.g. if someone exploits AutoBlue - what could they do that would inconvenience anyone other than themselves?

I'm sure there are plenty of reasons, the major issue I can think of would probably be cracking software/allowing games to run without a disc etc, but is code security as important for offline apps?

Online, offline... Doesn't matter. And I mean for C/C++ becuase the JIT compiler along with .NET development in general does lots of things that those category of programmers can take for granted. I realize this though and so I've become more aware of it. Garbage collection, memory management, etc... And comparing C to C++, exception handling is much more refined and easier to deal with in C++ than it is in C, but both, depending on how you write the code, are prone to buffer overflows in code, which is not good. You need to know how much space you are taking up for the space that you have allocated, and most commonly people make this mistake with bits vs. bytes, and char (1 byte) vs double-byte (2 char or Unicode more commonly) characters in arrays.

Especially for malicious code writers, if there's an exploit found in some AV, just for the sake of dramatization here, who's to say that I can't take advantage of that and inject my own shellcode into the memory of the process itself to run whatever I wanted for remote code execution?

I could have made an example of that, but for showing how to run code in another process' memory, I don't think that would be a very good thing for me as there is potential for it to be used for malicious purposes. That's one of the reasons for why my post is more informational instead.

Just because it doesn't interact with the network doesn't mean that there is no secure information locally that a hacker could use to their advantage. They could potentially use some methodologies in combination with this to retrieve all of your saved IE passwords, use a keylogger or some kind of remote administration tool to see what you are doing and log every keystroke you are making, or even potentially grab something like your Windows logon password.

This alone might seem meaningless, but how many people do you think probably use the same passwords for multiple sites? If I had your Windows logon password, and I knew what site you used to do your online banking on, why would it not be logical to make 1 + 1 = 2, and try to combine the password with that site to see if I could grant myself access? This is why I use all different passwords between secure locations that I want, well, secure.

I make it a personal effort to tell everybody that I know about this as well. Exploitations are always used to somebody else's advantage.

I would say for these reasons that any direct desktop program's code security, is more important than online apps. It's at the top of the tree and from which everything branches off of in my opinion. If I had a vulnerability in my website, I would still need to somehow trace it around to see who this person is and what I could do with the secure information I have unveiled. If I have access to the PC that the user is using though, everything is already there, and even more than you would want most probably. For anything more advanced, I might have access to the person's pictures, emails (local archives if saved), etc.

The greatest flaw in security is our blindness to realize what people can really do in my opinion. If more out there knew these things, and could recognize possible security threats, I would say that we would all be better off. 80% of everyone I personally know however, hardly knows how to manage emails in Outlook on their PC, and that is the problem!

:beerchug2:
 
Alright, so to improve on the beep code I got, I figured out how to get some of the 0x0's in the byte code by splitting the 32 bit register up into 16 bits so that the other 2 bytes don't get wasted for the values that I was using. If the arguments were values of ~0-255 perhaps 8 bit hi and lo would be used to avoid an extra 0x0, but otherwise I'm sure some bitshifting trick could avoid direct 0x0's upon interpretation...

Here's the ASM:
Code:
__asm
{
	mov ecx, dword ptr 0x764531AF
	xor eax, eax
	mov ax, 0x320
	push eax
	mov ax, 0x450
	push eax
	call ecx
}

(Note: With the calculated address specific to my system right now.)

And the derived shellcode would have been:
Code:
\xB9\xAF\x31\x45\x76\x33\xC0\x66\xB8\x20\x03\x50\x66\xB8\x50\x04\x50\xFF\xD1\xC3

Not a single \x00 (0x0). Just in case any of you were interested in a more efficient way.

:beerchug2:
 
Ace,

That is interesting. I just did this in Masm.

Code:
.486                                      ; create 32 bit code
.model flat, stdcall                      ; 32 bit memory model
option casemap :none  

include \masm32\include\kernel32.inc
include \masm32\macros\macros.asm
includelib \masm32\lib\masm32.lib 
includelib \masm32\lib\kernel32.lib

.code
start:
    invoke Beep,750,300
    exit
end start
 
Last edited:
lol That is cheating :r1: It makes this too easy. Although that wouldn't be good here... See those parameters for the Beep function are being interpreted as 32 bit sized values; regular 4 byte (32 bit) integers.

Code:
001B21A0 68 2C 01 [COLOR="#FF0000"]00 00[/COLOR]       push        12Ch  
001B21A5 68 EE 02 [COLOR="#FF0000"]00 00[/COLOR]       push        2EEh

You only really need a 16 bit storage for those values. Otherwise you'll get 00's like as seen above. That's why I split the 32 bit register into 16 bit to use for the arguments; it only takes 2 bytes (16 bits) to store both 0x12C and 0x2EE. 32 bits is overkill, and you don't want 00's in shellcode for the most part.

:grin1: The Beep function is one of my favorites though, even though perhaps one of the simplest.
 
Last edited:

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top