Stripping Upatre Trojan Downloader

Upatre is a trojan downloader widely used to download banking botnets . It recently started using compression and XOR encoding . Upatre comes with a custom packer . After unpacking real nasty evil code is revealed . Unpacking Upatre is little bit tricky . Following Blog post will show you how to unpack and rebuild Upatre.

This is what Upatre looks like when you open it up in a debugger .


If we skip the decoding routine . We land at OEP which looks something like this.


Calls like CALL DWORD PRT SS :[EBP + 30] are windows API calls. Before jumping to the OEP all the API call addresses are pushed on to the stack . So building a IAT for this type of packer would be a tricky job .

Tracing API calls. #

For tracing the destination of all these indirect API calls made after OEP , we will parse a trace file . One thing to take care of is the installer and downloader . So we have to trace for both the installer and downloader basic blocks . This can be done by patching some jumps in the file .


A jump is where the installation path is checked with the current path , another is when the original file is set up for deletion .

After running the trace on both the patched and non-patched binaries , we will concatenate the result and get the following result ( only CALL’s are filtered out )


We will log the destination address of these Each API calls . For that purpose we will create an immunity debugger’s pycommand script to log the API calls .
Sample pycommands file to hook at CALL [EBP =- X ] functions

import immlib
from immlib import LogBpHook
dbg = immlib.Debugger()
import struct
class Myhook(LogBpHook):
def init(self):
def run(self, regs):
imm = immlib.Debugger()
opc = imm.disasm(regs['EIP'])
CallDis = opc.getDisasm()
imm.log("Disasm = %s" % CallDis[CallDis.find("[") + 5: CallDis.find("]") ])
disp = int(CallDis[CallDis.find("[") + 5: CallDis.find("]") ], 16)
addrx = regs['EBP'] + disp
imm.log("Address = %d" % addrx)
addr = imm.readLong(addrx)
fp = open("addrs.txt", "a")
fp.write(imm.getFunction(addr).getName() +","+ str(regs['EIP'])"\n")
def main(args):
bplist = []
fp =open("Calls.txt", "r")
for i in fp:

bplist.append(int(i.split()[0], 16))
logbp = Myhook()
for i in bplist:
funcName = dbg.getFunction(i).getName()
return "done..."

This script will parse the run trace file and will put a log breakpoint on each function to recode the destination and save it in a file .

Later on we can read the file and name the indirect functions again using a
pycommands script.

import immlib
def main(args):
fp = open("addrs.txt", "r")
dbg = immlib.Debugger()
for line in fp:
addr = int(line.split(",")[1],10)
name = line.split(",")[0]
dbg.setComment(addr, name)
return "Done..."


This script will automatically generate names at the indirect call addresses.

Creating a Loader for dump file #

Upatre OEP code is a position independent code , but it depends on address pushed on the stack after dumping the .text section we can place it inside a PE skeleton and place our loader there .

For a skeleton exe we will use this awesome nasm file :( by Alexander Sotirov.


And in the loader stub we will copy all the stack address and push it .


After compiling this nasm file , we will get an exe file as an output with all names and strings visible .


Happy Unpacking

Raashid Bhat


Now read this

Notes On Vawtrak Banking Malware

Use of Heavens Gate technique for switching between 32bit and 64bit Packed file is compressed and encrypted using several layers , discussing that would be irreverent here . At one point of time the a DLL is extracted which is actually... Continue →