>> Now we're going to do
a unpacking demonstration where
I will use UPX to pack Regshot,
a tool that we demoed earlier because it's
a simple executable that we're going to look at
the strings as we have before and after packing,
and show how we can unpack with the UPX tool itself.
That's quite unique. With most packers,
they don't offer an unpacking tool built-in.
Some reverse engineers may make
their own UnPacker, or unpacking scripts to help.
Every once in a while,
someone in academia, or someone
in the industry will say
>> they have a universal UnPacker,
>> but it's usually not what they say it is,
or they're being very misleading,
or they're just being very general.
Because, there are some more advanced packers
out there that is really not possible.
I will talk about that in a little bit.
But for now, I will show you
>> how to manually unpack UPX,
>> and this technique will work with many other packers.
>> Then, we can just dump the process,
and then reconstruct
an important data structure called the IAT,
the import address table.
That is very useful because we can actually see
what the dependencies are for the executable.
Here I've reverted the VM back
to its ready to be infected state.
I will just drag over a few tools we're going to use.
The first is OllyDbg 1.1.
Because if we open an executable,
it's packed with UPX with Olly 2.0.
It will automatically unpack it for us.
That defeats the point of doing it
manually so we can figure out exactly what's going on.
Another one is Import REConstructor,
which I will demonstrate here in
a bit to help us rebuild the IAT.
UPX 391.
This one I demonstrated earlier, and PEiD.
I'm just going to drag these over here.
As I mentioned before, we're going to
take Regshot copied over to
the desktop and execute just to make sure it works.
It does. Now, we're going
to run PEiD on it to see if we get any detections.
Nothing found. Sometimes, we have to do
more deep scan to see if it finds
anything, and it hasn't.
Now we can go ahead and pack Regshot here,
I'm going to copy this over to the desktop,
type in CMD,
that only works with Windows 7.
To control our CMD and CD to the desktop.
Then do upx.exe and do
Regshot file, because you didn't actually do it.
Regshot X86.
It's trying to go after the shortcut.
We compressed it by 60 percent.
That's quite impressive. We can
run it again just to show that it does work.
If we look at the strings from the
original and the strings
after it's been packed,
we can see there's a lot of stuff
beforehand, and next to nothing after.
There's strings in both, but there's more in
the unpacked version, and the non unpacked version.
We can drag Regshot again over to PEiD, and it
immediately detects that it is UPX.
There are other indicators,
such as the section names are all renamed,
UPX0, UPX1, etc.
[LAUGHTER] PEiD can actually
allow for a lot more customization
in its signature detection.
Like user db.txt can be
modified, and you can put in a name of
packer and give it
a signature of a series of bytes it should look for.
That is useful. If you just Google around online,
people have made huge databases
of signatures for packers,
and I suggest that you grab one of those.
I've seen sands put out one,
I took 30 seconds to download it,
and found that they messed
up some encoding and it didn't really work.
I'm sure I could figure out.
But I saw that other people
have released other large databases as well.
I haven't ever had a problem with PEiD,
but I'm sure more signatures can't hurt.
There's a lot of false positives out there
sometimes, I found,
but it always helps
to just give a 30-second scan for something.
If we knew something was packed with UPX,
we can simply run
upx_d, and give it the name of the executable.
It will do its best to unpackage itself.
We can see that this executable works again,
and UPX is just unpacked.
That works pretty well a lot of the times because
the Burgo is just one of the packet to obviously get
the strings, or just change the hash, or whatever else.
Sometimes it does work,
but [LAUGHTER] I think there was a vulnerability in
the unpacking portion of UPX.
If people run upx_d on the
>> specially crafted executable,
>> it would actually turn remotely execute code.
If someone wasn't running this in
a VM, there would be infected.
Be careful, and I like to keep all the tools
inside the VM as best as possible.
Sometimes, a minor change would make
it so that UPX could not just automatically unpack it,
like the section names.
>> Let's see if we have a PE Explorer, not really.
I usually have one installed
but if we look at the section names,
let's see if we have a binary template.
We do not, but I can look
pretty easily here,
>> and see the section names.text.rdata.
>> If we do UPX, just repack it.
I'm surprised it didn't complain that
the vowels are altered.
Here, it's packed, and the section names have been
changed to UPX0 UPX1.resource.
If we were to change the section name,
it doesn't actually matter,
or just UPXX and save it and try to unpack it.
[NOISE].
It would do its best,
and sometimes it would work.
>> But if we change it again and save it,
>> then not packed by UPX, I think we corrupted it.
[LAUGHTER].
Let's delete it and start again.
Regshot, press it over here, 64 bit,
this is 60X86,
we pack it, we look at the section names.
We'll change one of the section names, save it.
This still runs just fine.
Let's see if UPX still recognizes
it when we try to unpack it, no.
Just by simply editing a small bit of the file,
UPX can no longer just unpack it by itself because it
uses some of those indicators
to unpack it properly because it
knows it's the packer that built the executable.
Unpacking automatically won't always work.
We can see here that we still got that signature.
We can do a deep scan,
hardcore scan, and it's showing
the wrong version for that packer.
It was showing the wrong version for UPX,
and we were actually using a different version.
Maybe if we downloaded
a new database file it would catch that but maybe not.
Someone even might have taken
the source code that doesn't help.
The PID is no longer developed.
You can get off the Internet,
but it's no longer maintained so if there's a bug,
there's a bug and you can't fix it.
But, if someone has
a bad signature out there or whatever,
or someone took the
>> UPX source code, and modified it more
>> then we have to unpack it manually, if we want to
get at the decryptor strings
and other resources in the file.
Here I've taken an original old OllyDbg 1.1.
It's saying a newer version of
the DLL corresponding to the system directory,
delete the old library.
Yes, I want to use the newest library.
I'm going to add a plugin to help us.
It looks like the plugins are just dropped in
here and the plugin is OllyDump.
I'll tell you about why
>> this is going to be useful later.
>> Going to restart Olly.
Drag Regshot into it.
It says hey,
look it has a high amount of entropy,
is probably packed are you sure you want to continue?
Because it knows that there
might be some funkiness going on.
We can even execute it
>> and it'll still work but there is
>> a process being executed by OllyDbg.
The first thing that is really
important is this PUSHAD instruction.
Let me see if I can make the appearance a bit more
friendly, terminal 6.
[NOISE]
PUSHAD is an instruction
that pushes all the registers onto
the stack and that's unusual
because compilers don't usually admit this instruction.
It's a bit slow, but it's frequently used by
packers because it easily saves the environment.
They can do a pop AD at the end of whatever they're
doing whatever witchcraft and they
can ensure that the same options
are there for their regular program
as they were there for
the packer or
the unpacking stub that's
at the beginning of the program.
We know that the original program is going
to use whatever is pushed
onto the stack so we're going to do a step over.
We're going to let all these values get pushed
onto the stack right down here,
and we're just going to
let it unpack the whole executable.
ESP is the extended stack pointer
and is pointing at the top of the stack,
so that's where all these values
just got pushed onto the stack.
I'm going to say follow and dump, expand this.
We can see over here these are
the values that are over here that have been
pushed onto the dump or push onto the stack,
and I'm going to just put a hardware breakpoint
right on access Dword,
so that's 32 bits,
aka, four bytes, and I'm just going to hit "Run" and
let the whole unpacker unpack the original code.
We can see that it accesses the values it pushed on.
Right here it does a pop AD
and put everything back in its registers.
I can see here that it's going to do a jump,
and that's probably going to be the jump
into the original code.
I'm going to say let's start walking through this.
But there's this little loop
here and the only way to get out of
it is for this condition
to allow this jump not to happen.
I know this is going to happen eventually.
I'm going to hit a breakpoint, hit
"F2" for a soft breakpoint.
Don't really care that it's hard or soft.
I'm just going hit "Play"
>> the hard breakpoint hit again,
>> but I'm just going to hit "Play" again.
It's now reached this breakpoint.
I want to remove it by pressing "F2",
and I know it's going to jump into the original code.
I'm going to say follow into
and here is the original code
that's now been unpacked. That's fantastic.
Now I can scan for strings and do all this other stuff,
but I really want it back into
a file form or I can just transfer it
to somebody or do some more stack analysis of the data.
I'm going to dump what
I have in memory right here into a file.
I can do that with that OllyDump program,
add plug-in that I mentioned earlier.
I'm going to say dump debug process.
>> There's our section AA that we edited.
I'm going to get EIP as OEP.
Now, this means that, I'm going to say,
this current area that
is about to be executed right now,
that is the original entry point, the OEP.
I'm going to copy that value too,
Control C. This is
important because the file on disk that's
packed says that the beginning entry point
is actually in the packer stuff.
The thing that does the unpacking, the decrypting.
We don't want that to be true anymore,
we want the original unpacked code
to just begin executing.
This is an old plugin,
OllyDump, and that's okay.
It tries to rebuild
the import table for us
>> and that can be a little tricky.
>> I've used method 1 and method 2,
and they've always worked for me unless it wasn't
a really simple program.
In general, I turn this off and
let another program help me out with that.
I'm going to dump this to disk,
and I usually say, whatever it is, underscore unpacked.
Save it. This is still executing
the memory even though the window hasn't popped
up or nothing else has been initialized,
it just unpacked the code.
I'm going to use my import reconstructor program.
Before I launch into that,
I just want to say that there are
other dumping programs that we can use.
This plugin for Olly,
there's Load PE,
a program that we have here that I introduced early on.
I can demo it real quick.
The more I can select which thing,
which process running,
I want right here.
I can say, "Dump" and create a folder, Partial Dump.
It's a dumper so it has a lot more options to it,
and it will even help you rebuild things in the PE.
But for simplicity's sake,
I'm not going to be showing that off.
There's even a newer Olly Plugin Dumper,
but the old one works just fine for
>> a lot of my purposes.
>> That one's called OllyDebg PE Dumper or PE Dumper.
[NOISE] Here, I'm moving on to
the next phase which is
rebuilding the import address table.
There's a lot of options to this.
I suggest that you take a look at them.
But for right now, I'm just going to rebuild
this executable as fast as I
can because it currently will not work.
If we double-clicked on it,
it would say, "Hey, the Windows loader says,
I can't find which dependencies this executable needs
and then tries to execute the code
and the code doesn't quite work."
But it's already been loaded up in the memory,
and it's still currently running even
though it's been halted by Debugger.
We can use Import Reconstructor to look at
our processing memory and find
the proper import address table.
Because the packer has already done this work for us,
we don't need to do it again,
we can just take a look at what it's done.
I'm going to go here to the OEP and paste that value in
that I had earlier and say,
"Okay, I want you to make
>> this the original entry point.
>> When this file is executed,
I want it to jump straight to the unpacked code,
skip the whole unpacking stub that UPX added in."
Now, I'm going to hit the "IAT AutoSearch".
I'm saying, break into
this process and look through its memory,
and find what looks to be an import address table.
It says it's found one.
It looks about right but hit,
"Get Imports" and we do,
and there are several DLLs loaded,
and we're just like, "Okay, that looks good.
That looks about what this program would probably use."
A good method to verify that is show invalid.
Say, "Go through that and look to see which ones
are not real that are messed up or something."
Then you can get an idea for where
exactly the import address table really is.
If you wanted to, you could,
with Olly, find that import address table.
All you have to do would be to find
the inner module calls which we
showed beforehand and find
a table where if we looked through the memory enough,
we would find an easy table where it would show,
this is the GetFileTime function,
and the FindClose function,
and the FindNextFileA function,
and so on and so forth.
Like I said, we could find
the import address table manually in Olly,
and there's plenty of tutorials out
there to find it efficiently.
But fortunately, the man who made this,
[inaudible] made
some clever algorithms to find it for us.
Now, we have what looks to be
the IAT and we have the DLL dependencies
that we need to make a functioning PE executable.
Here, I'm going to say, fix a dump.
The guy who made this was pretty smart
>> and he was saying,
>> "Okay, they've probably already have
a dump of the file
and here with my program, I can repair it.
I can build the IAT table
to what it looks like in memory."
We can select the unpacked non-functioning executable
that we have here, and boom,
it creates another executable,
copies everything over,
adds an underscore to the end of that file,
and inserts an IAT that looks just like this one,
that looks like the one I found in memory.
If we execute this one now,
it completely bypasses the unpacking coach
straight to the unpacked code.
That's how you manually
unpack a file if
you don't have the luxury of using UPX-T.
The same technique of using the Push AD and
Pop AD instructions as indicators for when
to follow a jump into the original entry point,
dump the code, and then use
import reconstruction program
>> like import reconstructor.
>> This will work with a lot of packers out there
such as AS Pack and a few other common ones.
There are many tutorials on there.
Tuts 4 You is a great website
for finding tutorials on reverse engineering packers.
There's a lot of automated scripts
that people have made for Olly to
help you find certain data structures
or to help you just unpack things.
In fact, when I Googled around a few minutes ago,
I found someone made a unpacker for Olly,
and it did almost exactly what we did here which was
find the push AD instruction
and find the Pop AD instruction,
place a breakpoint, dump it,
and then reconstruct it with the import address table.
But it's good to know what's going
on underneath the hood.