PE File Infection

Oh sweet. Is that just simple metadata modification? Also, would that affect the signature? I would like to find a way to sign executables so as to remove the “this publisher isn’t trusted” message.

1 Like

Yeah, I guess. If you’re infecting an executable by adding extra data, of course the resulting binary’s signature will be compromised. If you want to sign an executable without the warning message, you’ll need to acquire a certificate from a trusted authority like Verisign, or perhaps you can check out Microsoft’s SignTool.

2 Likes

Avoiding the untrusted publisher pop-up would be simple, we just need to steal Microsoft’s private keys which they use to sign programs.

As to changing file modification dates, it will be easy to do. You can do it with powershell or python.

1 Like

Shouldn’t you use OPEN_EXISTING instead of OPEN_ALWAYS when calling CreateFile?

If the file doesn’t exist, OPEN_EXISTING will return an error code. OPEN_ALWAYS will create a new file if it doesn’t already exist, you then call GetFileSize and retrieve the size of the empty file and attempt to map the empty file into memory.

MSDN (CreateFileMapping function’s fourth parameter):

The low-order DWORD of the maximum size of the file mapping object.

If this parameter and dwMaximumSizeHigh are 0 (zero), the maximum size of the file mapping object is equal to the current size of the file that hFile identifies.

An attempt to map a file with a length of 0 (zero) fails with an error code of ERROR_FILE_INVALID. Applications should test for files with a length of 0 (zero) and reject those files.

^ “Applications should test for files with a length of 0 (zero) and reject those files.”

CreateFileMapping & MapViewOfFile will both fail if CreateFile creates a new file. CreateFileMapping fails because the file size of the newly created file is zero and MapViewOfFile fails because CreateFileMapping returns NULL to its handle after failing. CreateFileMapping returns ERROR_FILE_INVALID(1006) and MapViewOfFile returns ERROR_INVALID_HANDLE(6). Change CreateFile’s dwCreationDisposition parameter to OPEN_EXISTING.

2 Likes

Great post! It really opens up a whole new window of opportunity! I’m stoked to see what you may have in store for us next.

Yeah, you’re right. Guess I wasn’t paying attention while coding. I’d fix it it the thread but it doesn’t give me the edit option so, can’t really do anything about it.

1 Like

Nice tutorial thanks !

Could you give me an explanation about the part where you try to search in the shellcode the placeholder 0xAAAAAAAA ?

To be more specific:

  1. What do you mean about “placeholder”?
  2. The placeholder 0xAAAAAAAA seems to be the same for the lpAddress and the dwOEP…why?
  3. Furthermore, in the ShellcodeStart function, a first call is made with 0xAAAAAAAA into eax and a return is made with the same value pushed on the stack…can you explain that part more precisely/easily?

Thanks for you work :slight_smile:

Hi,

Could you elaborate a bit more on the “delta offset” technique? I think it’s not that immediate why it’s needed. If I understand correctly, the reason is that the shellcode won’t be loaded at its preferred virtual address most of the times, so we need a way to compute the difference between that address and the real one.

From your description, it seems the result of sub ebp, offset routine is always 0, which doesn’t make sense (in that case we wouldn’t need any trick and a simple xor ebp, ebp would be enough). So, from what I understand, the result of that subtraction won’t likely be 0 and that’s why we need the delta offset technique. What do you think?

Hi @Duke_Nukem,

  1. In this context, you can consider the placeholder as a “fake” virtual address that will later be replaced by the real one. That’s because you don’t know where the MessageBoxA function will be located in the virtual address space of the target process. The same applies for the entrypoint: you need to get the OEP at first, and then patch the shellcode.
  2. Yes, they are the same. It doesn’t matter, since they will get replaced at runtime.
  3. The shellcode is executed after being patched. This means that the first call will actually call MessageBoxA, while the return will actually return to the OEP.

Hope this helps you to better understand :slight_smile:

3 Likes

The delta offset method is required for situations where you cannot determine where your values will exist in the virtual memory space of the process (or host) since there are some dynamic elements such as the innate differences of files, base relocations, etc.

Is that what you were looking for or were you looking for something else? Perhaps this link might provide some insight: https://cranklin.wordpress.com/2016/12/26/how-to-create-a-virus-using-the-assembly-language/

3 Likes

Hi, I’m running your code on a 64-bit windows system, but using VS x86 debug mode and the exe file is 32-bit too. The problem occurs on *((LPDWORD)lpHeap + dwIncrementor) == 0xAAAAAAAA , it couldn’t fine a suitable dwIncrementor that meets the requirement. What should I do? Does the code must be running on a 32-bit windows? THANK YOU SO MUCH if you can answer me !

Try debugging the loop and check to see if there are any alignment issues, e.g. it gives you values like 0xAAAAAA or 0xAA If there are, you can simply add nops to the realign the assembly.

This does require a File2VA() function as we are mapping the file.

Shellcode contents are not copied into heap.
Memory 1 - Shellcode
Memory 2 - Heap
So loop fails to find 0xAAAAAAAA and program fails!
Any help would be appreciated

Can you check if HeapAlloc was successful and lpHeap contains a valid address?

Everything is ok…but still no output

Try replacing the heap with a buffer variable large enough to hold the shellcode.

1 Like

It worked! Thanks buddy :thumbsup:

finally something tasty to use , great article!

This topic was automatically closed after 30 days. New replies are no longer allowed.