Welcome to the new Woodmann RCE Messageboards Regroupment
Please be patient while the rest of the site is restored.

To all Members of the old RCE Forums:
In order to log in, it will be necessary to reset your forum login password ("I forgot my password") using the original email address you registered with. You will be sent an email with a link to reset your password for that member account.

The old vBulletin forum was converted to phpBB format, requiring the passwords to be reset. If this is a problem for some because of a forgotten email address, please feel free to re-register with a new username. We are happy to welcome old and new members back to the forums! Thanks.

All new accounts are manually activated before you can post. Any questions can be PM'ed to Kayaker.

revisiting code guard or virtual protect

All-in-one reversing related discussions
Post Reply
WaxfordSqueers
Senior Member
Posts: 1000
Joined: Tue Apr 06, 2004 11:00 am

revisiting code guard or virtual protect

Post by WaxfordSqueers »

Trying to unpack a dll but I don't have a 64-bit LordPE...correction PEid type of tool. Just d/l'd the updated one from Evaluator but don't know if it does 64-bit apps.

In the section layout there are references to WUS0 and WUS1. WUS0 is empty at first and when the code is executed, the bytes in WUS1 are decoded and put into WUS0. Then the IAT seems to be partly rebuilt at an addy in WUS0 since many functions pointers are written to that address. I am sure the IAT table still needs to be reconstructed.

The MZ and PE headers are mangled so they'd need to be rebuilt if I can't get past the virtual protect nastiness. I think the virtual protect function is just before the MZ header rebuild because I see a reference to it in an x64dbg window.

BTW... for Blabbs, I have been using windbg on the dll mainly, and quite successfully. I switched to x64dbg only to get a better visual presentation, so I could see more at one time. Have been using !peb to get the base address of a loaded executable then !dh on the base address in !peb to get the code entry point. Then I combine them as a BP. Voila...straight to the entry point.

I was going along swimmingly till I hit a reference to virtual protect, and I thought, "Uh, oh...that sounds like trouble". Sure enough it was big trouble. The debugger x64dbg, froze at a ret which was obviously trying to read a protected page. Have not tried to analyze the virtual memory protection code yet but I recall Kayaker talking about some kind of code guard in an earlier post.

Apparently the virtual protect function takes a memory address, a size, and an integer to indicate read, write, or execute. There is one other parameter as well. I could likely finagle my way through that but, as you all know, there is verification code behind that code to make sure you don't get away that easily. And if you change bytes, there will likely be encryption of some kind.

I tried fooling it by changing the memory address for its input but as I understand it, from some reading on the subject, memory pages can be protected on an 'as needed' basis. So, maybe some pages were protected early on in the code.

First, I'd like to identify the protection and to see if a tutorial has been written on it. If Lord PE (see note below), modded by Evaluator does not work, is there another tool that will evaluate protection on a 64-bit app?

Correction...I have confused Lord PE with PEid. PEid enhanced reports it as having no protection or an unknown protection. Can't believe that since the MZ and PE headers are mangled, the IAT is missing and the sections are modded. PEid is quite old but I just found a newer version from 2016.

ps. d/l'd the latest version of PEid, now called Protection ID, and it reported the protections as UPX. Not sure if that is a packer or a protection...rust!!! The URL for several versions is:

https://protectionid.net/
blabberer
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Re: revisiting code guard or virtual protect

Post by blabberer »

hi wax,

its nice to see some !peb !dh stuff just try @$exentry and you don have to do both of the previous maybe.
WaxfordSqueers
Senior Member
Posts: 1000
Joined: Tue Apr 06, 2004 11:00 am

Re: revisiting code guard or virtual protect

Post by WaxfordSqueers »

blabberer wrote: Sun Jan 17, 2021 11:23 pmits nice to see some !peb !dh stuff just try @$exentry and you don have to do both of the previous maybe.
Good to hear from you again blabbs. You told me about @$exentry before and I have used it but I was trying out !peb and !dh to see where the based address and entry point were located in the peb.

Besides, either method only gets me to the entry point of the packed dll. I got stymied for a bit with the VirtualProtect function, trying to understand what it does. The key for me was in the flNewProtect parameter which was set by a PUSH 4 just before the function call. By changing it to 0x40 it got me past the function. The 4th param, lpflOldProtect, is a pointer to where the old protection was stored. I changed that to 0x40 as well for good measure.

BOOL VirtualProtect(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flNewProtect,
PDWORD lpflOldProtect
);

Right after that code, however, I ran into an apparent single-stepping test with calls to getsystemtimeasfiletime, getcurrentprocessID and getcurrentthreadID, followed by a call to QueryPerformanceCounter. They take time values and the QPCvalue and add them to the process and thread IDs separately and arrive at a cmp and cmove instruction which swaps rcx with rax based on the conditions from the cmp. I found that by manipulating the flags changed by the cmp back to the original condition that the debugger carried on OK.

After that, a process begins to encode the IAT addresses of various functions. It's fairly simple though. The import address is xored with a magic number and xoring them with the same number gets them back.

I forgot, that prior to that action, the EncodePointer function is called twice. Not sure yet what it does in this app as yet. Has the form:

PVOID EncodePointer(
_In_ PVOID Ptr
);
User avatar
Kayaker
Posts: 4169
Joined: Thu Oct 26, 2000 11:00 am

Re: revisiting code guard or virtual protect

Post by Kayaker »

Hi Wax,

The clue about UPX and what seems like renamed WUS0 and WUS1 sections is interesting. If you can get past the custom packer you might be able to peel it back to more traditional upx code, for which there was sort of a recipe for navigating that code - bp's on n# pushads popads and such-->OEP.

Setting a bp on a possible early API, GetVersion, GetCommandLine, etc. is sometimes useful when stuck in unpacker code, at some point the bp might hit if you let it run, and you can get at least an approximate OEP by scrolling up the debugger, and check import tables.

Reviewing upx unpacking techniques on notepad might be useful in order to recognize differences from any custom wrapper you might have.

K
WaxfordSqueers
Senior Member
Posts: 1000
Joined: Tue Apr 06, 2004 11:00 am

Re: revisiting code guard or virtual protect

Post by WaxfordSqueers »

Kayaker wrote: Mon Jan 18, 2021 10:37 pmThe clue about UPX and what seems like renamed WUS0 and WUS1 sections is interesting.
Kayaker...thanks for reply. It seems apparent that WUS0 and WUS1 are meant for unpacking since WUS0 is empty in the disk image and WUS1 contains the code to be decrypted. After decryption, WUS0 contains a whole lot of code that can be decoded in IDA.

I dumped that code and loaded it as a binary in IDA. Of course, I forgot to set the IDA code to the same base as the code in the dll loaded in memory so some of the jumps and calls make no sense. All the same, the code is readable to an extent and I can plainly see where the .Data section should be and resources.

Since then the decrypter has added IAT imports as memory pointers then later it encrypted the real imports. I likely have enough info to rebuild the dll image but I am hoping they will create the MZ and PE headers. If so, I can load it in IDA and see what's what. Meantime I am on the look out for anti-debugging tricks.

Should note the dll seems to call a dll loader at some point. Don't know if that in itself is an anti-debugging trick. At the entry point it jumps to code that calls IsDebuggerPresent. Or, maybe someone else has already reversed it and added the loader. Reversing the main dll is not critical but it's a spoke in the wheel so to speak. Being able to look at it in IDA would help explain the rest of the code external to it. However, it is encrypted.

Interesting stuff but very intensive tracing to get meaning from it. Have not seen an obvious CRC checkbut I'm sure it's coming.
Post Reply