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

How I Contacted Russian Hackers Via Telegram

Furthermore, Tracing Their Geographic Coordinates # Introducing Botgram, the epitome of innovation in the world of international diplomacy! Because who needs secure channels and established communication protocols when you can have a... Continue →