start	end	text
25080	30340	Okay, hello everyone. My name is Paramount Kid and I welcome you to Reversing with Dynamic
30340	36060	Data Resolver. If you are not already in the Discord chat, please go to blueteamvillage.org,
36060	41600	click on the Discord channel link, and I would like you to give a warm welcome to Mr. Holger
42200	50780	and let's start with the talk. Hi and welcome to my presentation,
50780	56240	Reversing with Dynamic Data Resolver Best Practices. My name is Holger Unterwink. I'm
56340	60920	a security researcher at Cisco Talos and I'm mainly focused on malware research,
60920	65220	threat hunting, and tool development. If you want to follow me on Twitter,
65220	72800	you can find me at hunterbr72. I'm the author of DDR and I will guide you through the different
72800	79520	features of DDR today, the installation process, and I will show you some of the best practices,
79520	85920	how to use the tool, and some of the special cases and caveats which you can
86540	90560	see later on in the demos where you might can run into.
92920	99260	So what is Dynamic Data Resolver? First of all, Dynamic Data Resolver is an instrumentation tool.
99260	106420	It is instrumenting the binary so that you can trace all the instructions the binary is executing
106980	114380	and it is collecting all kinds of data from strings to register values, memory locations,
114380	121780	etc. etc. It comes with an IDA plugin which is controlling the backend so you can easily
122420	129900	handle everything from this IDA plugin and you don't need to use the command line tools. You can
129900	138880	and I will talk about that later on. DDR comes with an client-server architecture.
138940	147400	So you have the DDR server which is running on the malware PC side, so the PC where you are
147400	154960	executing malware, and you have the IDA plugin which is running inside of IDA on the analyst PC.
154960	160940	It is highly recommended to separate these two machines. In theory, you can run all of that
160940	166900	on one machine, but keep in mind that you are executing the malware at the end.
166900	173140	So the malware really runs on that machine and you might not want to infect your machine
173140	180120	where you have your IDA installation on. It'll be infected with malware.
182940	193500	So what can I do with DDR? DDR was mainly built to resolve dynamic values and this is why I've
193500	199320	called it a dynamic data resolver. But it comes with all kinds of other features. But for now,
199320	205120	let's keep with the data resolving option you have in DDR. You have the option to resolve
205120	214440	certain register values, for example. So if you want to know the absolute value of EDI or EBX or
214440	222520	EAX, you can just do that with one click. You can also get the pointer to the memory this value is
222520	229560	pointing to, or even the pointer pointer. And DDR also tries to detect if the address which is
229560	238440	stored in a certain register, if that one points to a certain API call like virtual protect.
238660	246940	And if that is the case, it will also resolve the API call so you can see the human readable name
246940	258850	of the function call. After you have run a trace and DDR has all the instruction traced,
258850	266510	you can highlight the instructions with a color. You can just highlight them depending on how many
266510	273510	times they were executed. So you get a pretty quick overview about which basic blocks were
273510	279150	executed by the program and how often these basic blocks were executed by the program.
279190	287410	As you can see here on the slide, if you see a color which is a more warmer color,
287410	292830	like red or purple, you know that this basic block or these instructions were
292830	299730	executed many times. So it is likely that it is maybe a decoding routine or something like that.
299730	303270	So that already gives you a good clue about what the sample is doing
303270	309070	and what parts of the sample are executed and what other parts are maybe not executed.
310330	319890	You can also get a table of all the API calls the sample has executed. So you can search
319890	326550	through this list. You can search for certain API calls like a virtual alloc or something like that.
326550	331830	And then you can do a double click on the line and you are jumping to the disassembly code
331830	339990	where this API call was called. The same applies for strings. As I mentioned earlier,
339990	346790	DDR tries to collect all the strings at runtime. And it is filling this table with these strings.
346790	352910	And the table is again searchable. So you can look for certain interesting strings like PE,
352910	358970	for example, if you're looking for a PE header, and then double click on this line
358970	366890	and check out in the disassembly what's going on where this was used.
366910	370530	And we will see all of that later on in the live demo.
373580	379100	Another neat feature of DDR is that there's a smart way to dump buffers at runtime.
380020	390120	So all you have to hand over to DDR is the size of the buffer, the address of the buffer,
390120	398700	and when or where you want to dump the buffer. And we will also see that later on. For example,
398700	404020	you just have to mark the operands in the disassembly which are storing these
404020	409960	informations. The size, the address, and at the end where you want to dump the buffer.
413600	417660	Unfortunately, often malware comes with anti-analyzing features.
417660	422520	And it is not executed like it would be executed on a normal PC.
422540	429320	If you're running it in a VMware, for example. So DDR comes with an option to patch the sample
429320	435060	at runtime. So for example, you can knock out certain instructions. Or you can toggle the
435060	443560	E-flag and manipulate the execution flow. So if there's a conditional branch, you can just
443560	448420	toggle the E-flag and the conditional branch will do the exact opposite.
448640	452220	But again, we will see that later on also in the demo.
452540	458100	And last but not least, you also have the option to completely skip certain functions.
458380	463700	You can just mark a function, skip it, and return a fake return value.
464020	468500	So if you have, for example, a certain function in your malware sample which is
468500	476500	checking for virtual machines or for anti-debugging stuff, you can just skip the function
476500	483180	and return the value which is telling the sample that it is not getting debugged or that it's not
483180	488920	running on a virtual machine. But again, we will see that later on in the demo.
491220	499040	If IDA and DDR is not enough for you to analyze the sample, you can also create an x64 debug
499040	505960	script which is automatically executing the sample. So it automatically loads the sample
506590	513880	into x64 debug and it is automatically breaking at that address which you have
513880	520240	highlighted in IDA when you have picked this menu point.
520500	528520	If you don't like x64 debug, you also have the option to create a new executable of the
528520	535740	binary with an endless loop at the marked address. So you can mark a certain location or certain
535740	545160	address inside of IDA, pick this menu option, and then a new binary is generated which has an
545160	552920	endless loop patched at that location. So you can start the binary, it starts to loop endlessly,
552920	560080	and you can attach your favorite debugger to it, restore the bytes, and proceed debugging it.
562620	568500	Okay, that should be enough for a quick overview about what you can do with DDR.
568580	576380	In the upcoming demo, we will see all these features in detail again. So let's start with
576380	582800	the installation. Of course, first of all, you have to download DDR. You can get it from
582800	589720	its repository on GitHub. And once you have downloaded it, it comes with an installation
589720	596140	script. And pretty much all you have to do is to execute this installation script, and it will
596140	604360	guide you through the installation process. Again, we will see that later on in the next demo.
605440	611900	If you want to stay up to date with the latest versions of DDR, you can follow me on Twitter.
611900	619080	And every time I'm changing, fixing, or fixing anything, or releasing new stuff for DDR,
619600	629820	I will announce that on my Twitter account. If this presentation is not enough for the
629820	636200	information you are looking for, you can also find a very detailed blog post about DDR,
636200	641640	which I've released end of May on our blog, which is also describing the different
642820	646860	steps, the different features, and the best practices,
647340	653000	and the caveats which you have to be aware of when you are working with DDR.
656360	666320	DDR has a client-server architecture. Keep in mind that DDR is instrumenting the binary. So the
666320	675660	binary is getting executed at the end. So it is highly recommended to split the analyzing part
675660	681780	and the execution part, so that you have an analyst PC where your IDA is running on, including the
681780	688620	plug-in, and a dedicated malware PC where you are executing the malware sample and analyzing
688620	697780	the malware sample. The DDR server is controlling the backend of DDR, which is implemented
700280	706860	using the DynamoRIO framework, and that one is at the end executing the sample,
706860	713440	instrumenting the sample, and collecting all the data, which is then transferred back to the
713440	719300	IDA plug-in. But we will also see that later on in a demo.
722770	730870	Okay, so enough theory. Let's have a look how that looks in the real world.
732570	738130	Installing DDR is pretty straightforward. All you have to do is to execute the
738130	744190	ddr-installer.py script, and it is solving all the dependencies for you.
744890	751370	After it has downloaded all the dependencies, it will ask you a couple of questions about the IDA
751370	758370	installation directory, the IP address it is supposed to listen on, etc. etc. And after you
758370	765470	have done that, you can start a local HTTP server, or in other words, the script is starting an HTTP
765470	774430	server for you. And then you can move over to the IDA machine and access this HTTP server and
774430	784090	download the DDR IDA plug-in site of the installation. Then you unzip the file and
784090	790850	copy over the content to the traditional IDA plug-in directory. That will change in the next
790850	798210	release, which is coming out very soon. And we will move over to the IDA user plug-in directory.
798710	803630	So that has the advantage that you will not need any administrative rights anymore.
805070	810450	Once you have done that, you need to figure out which Python version your IDA installation is
810450	818430	using. And then you need to install two dependencies for this Python version, the
819150	826610	requests library and the pfile library. And with this, you are ready to go. And you can move over
826610	835770	to the server side again and start the DDR server. Okay, so after we've seen how the installation
835770	844230	works, I can give you now a quick walkthrough of the different DDR features, which I've mentioned
844230	852850	earlier. Okay, for this end, we have a dedicated analyst PC where IDA is running on, including the
852850	860390	plug-in. And we have a dedicated machine where we are executing the malware on and where DDR
860390	870990	server is running on. So let's move to this malware machine. Once on the malware machine side,
870990	878390	we are starting the DDR server via the DDR server Python script. And when we are starting it,
878390	885390	there's a little hind that you have to be aware of, that there is a caveat with
885390	894710	Windows command prompt and Python scripts. If you're marking any text in the output window, you are
894710	902330	freezing the Python application. So that means that if the plug-in would try to talk to the
902330	910590	server now, you would run into a timeout. If that happens, you just need to
910590	917450	hit escape a couple of times or just do a ctrl z and restart the server if you like.
923310	925830	Okay, so let's move over to IDA.
930850	938170	The first thing you usually want to do is you want to run a trace. A trace is filling all the internal
938170	945630	data structures inside of DDR which are necessary for most of the other features. And you have two
945630	952290	options, either to run a light trace or a full trace. A full trace is a trace which is collecting
952290	958850	as much information as possible per instruction. So for example, it is saving all the
958850	966530	register values for every single instruction. A light trace is only collecting a subset for
966530	974010	these informations, but enough informations that you can have a look at the API calls, for example,
974010	981430	or at the strings which were traced, or to get a source operand. And a light trace is usually
981430	989530	something which I'm running when I start to analyze the sample. And if I just want to get an
989530	995190	overview, if I just want to highlight the traced instructions, for example, or if I just want to
995190	1002450	see the API calls, then the light trace is good enough. Later on, when I'm analyzing a crypto
1002450	1009090	algorithm, for example, and I need more informations, for example, all the registers,
1009090	1017570	then I'm running a full trace. But I'm only running a full trace for a small address range or
1017570	1025270	for a few basic blocks, for example. Because this is really time consuming and it is also consuming
1025470	1033190	a lot of memory. So you usually want to limit the amount of instructions which you are instrumenting
1033190	1035110	within full trace.
1037130	1044270	Okay, enough about traces. Let's run the light trace and check how that looks like on the DDR
1044270	1051930	server side. So the sample is executed and the dialog box which you have just seen just belongs
1051930	1058390	to the sample code. It doesn't have anything to do with DDR. Don't be confused by that.
1058390	1066010	Once the analysis is done, you can see that the trace log file is written to the same directory
1066010	1074950	where the original sample is located. And you can also see that the temporary trace files
1074950	1082670	were deleted based on a server command and then transferred over to the IDA plugin. So now we can
1082670	1090610	switch back to IDA. And we also see this method can switch back to IDA. And we also see this
1090610	1101510	message inside of IDA that the light trace was done successfully. So this means that DDR now has
1101510	1108090	all the information it needs. And we can execute other features like highlighted traced instruction,
1108650	1114910	which is giving us an overview about which basic blocks were executed or which instructions
1114910	1128580	were executed. Okay, so let's move to the next feature. You can nop out instructions at runtime.
1129580	1136560	So if you have certain instructions which you want to get rid of, like the dialog box which
1136560	1143560	we have seen earlier, you can just mark these instructions and you go to the patch menu in DDR.
1144060	1151030	And then the next time you execute the sample, so for example you run a new trace,
1151340	1157480	then these instructions are nopped out, they're not getting executed anymore. And you can see here
1158000	1165060	that it is responding much faster because we didn't have the pop-up of the dialog box
1165060	1174830	and the sample immediately proceeded with execution. Okay, the next feature which I would
1174830	1181330	like to show you is how you can use the dynamic values which were collected by the trace.
1181650	1187190	Now first we are doing a trace again. This time we are just doing a trace over a couple of
1187190	1194590	instructions. Now you're picking full trace for marked address range. And once this is done,
1194590	1201910	we have all the values from these instructions inside of the database. So we can just go to
1201910	1208310	get value for source operand and we are getting the value for RAX in this case.
1211140	1217560	Or we can just get the values from memory pointers like you can see here,
1217560	1222700	or all kinds of other information DDR has collected.
1249100	1255660	The next nice feature is that you can collect all the strings and API calls at runtime.
1256320	1264620	You can show both of them via tables where the DDR menu. So if we are looking at the strings,
1264620	1270680	for example, this is a list of all the strings which we have collected at runtime. And of course
1270680	1275960	you can also search for something in there, like PE for example. And if you're double clicking
1275960	1283000	on the line, then you're jumping to the line in the assembly where it is used.
1284640	1289620	You can also have a look at the API calls which were executed at runtime.
1289880	1296280	And again, the same applies like for strings. You can search for something and double click on it.
1296280	1301820	And then you see where it is used inside of the code.
1303880	1309660	You have seen earlier that you can manipulate the code flow by nopping out instructions.
1309960	1315240	But there are also other options inside of DDR which are manipulating the code flow.
1315240	1321780	The next one which I would like to talk about is the option to toggle the E-flags. So for example,
1321780	1327560	if we have a code like this, where we have a conditional jump and a comparison before,
1327560	1334440	then we can toggle the E-flag at the jump. In this case, you have to know that EAX can
1334440	1341680	never be bigger than 5. So at least in theory, this jump should always be taken in this code.
1341680	1347500	And the program should print out main A is not greater than 5.
1348560	1355000	If we want to manipulate that, we can just mark the GLAE instruction, do a right click,
1355000	1358360	and go to the patch menu inside of DDR.
1363270	1369750	Inside of the patch menu, we pick a toggle E-flag. In this case, we have to toggle the SF-flag.
1370370	1376330	And once this is done, we can now just run the sample if we want.
1376570	1386190	So for example, again over the patch menu, if we pick that one, then the sample is just
1386190	1394870	getting executed. But we could also use any other feature of DDR, running a trace or doing a dump,
1394870	1402830	which we will see later on. All these patches which I have applied will work for all the DDR
1402830	1413830	features. Once we executed it, then we can move over to the DDR side and check the output of the
1413830	1424370	file. Sorry, of the executable. So here you can see that the patch worked, and the program printed
1424370	1434160	out A is greater than 5, and this should never happen. The last option you have is you can skip functions
1434160	1442560	at runtime. So for example, if we have my function 1 here in this case, maybe something which is doing
1442560	1449400	some anti-analyzing, anti-debugging stuff, you can just skip it and you can fake the return value.
1449400	1455860	You're just marking the first instruction in the function, and you are going again to the patch
1455860	1464640	menu, skip function at marked address at runtime, and you hand over the faked return value, and that's it.
1468930	1472350	Now you can execute the sample again.
1473970	1482470	And if we are moving over to the DDR server side, we see that the sample is getting executed,
1483310	1491310	and in the output of the sample, we see that the my function 1 output is gone,
1491310	1495270	because the my function 1 is not executed anymore.
1495830	1503450	And another main function of DDR is that you can dump buffers at runtime.
1503530	1510610	And you can do that in a smart way. Later on, this string will be copied into this buffer,
1510610	1517210	which we are going to dump. So remember that for later. So for example, if you have a function
1517210	1524310	like virtualalloc, all you have to do is you have to mark the operand, which is storing the size of
1524310	1535090	buffer. Get buffer size. And the next thing is you mark the operand, which is storing the address
1535090	1544770	of the buffer, which you are going to dump. Get buffer address. And last but not least,
1545490	1552810	the final step is you mark the instruction or the location where you want to dump the buffer.
1559600	1568440	So use marked address to dump buffer to file. That's it. Now you can go to the dump menu and
1568440	1576420	execute the sample and the buffer gets automatically dumped at runtime. Once it is dumped,
1576420	1582360	it is transferred over to IDA and you can store it somewhere on disk.
1583440	1588300	And here you can see that it is the buffer which I've mentioned earlier,
1588300	1593460	where the program has copied the PE string into.
1596020	1605520	If you want to debug the sample inside of x64 debug, you can also generate x64 debug scripts,
1605520	1611720	which are automatically setting a breakpoint at the location which you have. So once you
1611720	1620920	generated the script, you can load it into x64 debug. All you have to do is to run the script,
1620920	1628990	it will automatically stop the sample and break at the breakpoint which you have highlighted in IDA.
1635320	1640420	So here we have reached the breakpoint, the script has finished,
1640420	1645160	and now you can proceed debugging in x64 debug.
1647260	1652900	The last feature which I would like to show you is how to create endless loops in binaries.
1653780	1659960	So if you want to create an endless loop, you can just mark the line where you want to create the
1659960	1668720	loop and then you select create executable with loop at marked address. Now DDR is creating a
1672660	1681560	patched binary and you can move over to the DDR server side and you will find a patched binary
1681560	1696630	inside of the samples directory. So now you can start this binary, just double click on it and
1697990	1702270	at a certain point we are reaching this endless loop.
1702270	1709630	So now we can attach our debugger to it and proceed debugging the sample.
1716280	1722940	So after pausing the sample, of course first thing you have to do is you have to replace
1722940	1728520	the patched bytes. The patched bytes of the endless loop will help in the DDR server
1729080	1734000	output to see what kind of bytes you have to patch.
1736520	1742040	Now you're just copying the address into this command
1743520	1751430	and then finally you have the original commands back inside of the binary.
1754540	1760220	So when we are proceeding to debug, you see that this changed to the original
1760220	1765200	bytes and now you can just proceed debugging like usual.
1765940	1767720	And that's it.
1770260	1776420	Okay, so this was the installation and the feature walkthrough of DDR.
1776840	1784340	Let's move on and have a look at some of the special cases and of course the best practices.
1784880	1789080	The better you know DDR, the more efficient you can use DDR.
1789660	1796440	And as usual, the easiest is to watch a quick live demo about it.
1798660	1805700	When I start analyzing samples, I like to run a quick light trace.
1805700	1813120	Light trace is only executing 20,000 instructions by default.
1813160	1816840	You can change this default value. If you're running a light trace,
1816840	1819640	you can probably set that up to 200,000.
1819640	1826040	But this is in this case for this sample not necessary, so we can leave the default value.
1829830	1836690	Once the light trace is executed, we can highlight the traced instructions to see which
1837470	1839650	basic blocks were actually executed.
1840550	1846070	This was pretty quick in this case, so let's see what's going on.
1846070	1851650	Highlight traced instructions and we see that there are only four
1851650	1854530	basic blocks which were actually executed.
1854530	1861390	So it seems to be that there is some anti-analyzing checks going on.
1861390	1867610	So let's go into the last function which might be responsible for this check.
1873400	1879220	So when we are scrolling down a little bit, we see that it seems to be that this function is
1879220	1884220	dynamically resolving the getNativeSystemInfo API call.
1884220	1889160	It's using getProcessAddress. We see that pretty often in malware samples.
1891950	1898470	Then it is storing the address in this variable.
1899870	1908130	And a bit later on, it is subtracting 10 from this address.
1908630	1920190	And a little bit below, we see that this value is pushed as an argument to the next function.
1920190	1924570	So it seems to be that the first argument of this function
1925070	1931410	is this getNativeSystemInfo API call function address minus 10.
1932350	1939850	So when we are looking at the first argument here, we see that it is executing a couple
1939850	1944970	of mathematical instructions. And it seems to be that it is just
1946650	1953170	adding 10 to it. So it has restored the original address.
1953170	1963170	And it seems to be that it is just calling the getNativeSystemInfo API call here at that point.
1963690	1969330	Unfortunately, in real malware, this is often much more complicated.
1970030	1978090	So in real malware, we often see that these calculations are distributed
1978870	1983190	all over the place. And they are heavily obfuscated.
1983190	1991090	So it's often very difficult to figure out what is actually called at this point.
1991170	1996150	With DDR, that is much easier. You can just do a right click,
1996150	2001150	and you can get the value of this function pointer.
2002070	2005690	Just pick getValue for pointer and source operand.
2009140	2014280	And then you see the value which was used at runtime.
2014800	2020660	So it is confirming what we assumed getNativeSystemInfo is called.
2022240	2026440	With this information, we can now go one level up.
2026440	2038620	And we can change the name of this argument to function pointer getNativeSystemInfo minus 10.
2039060	2046180	And we have also seen earlier in this function that there was one parameter pushed.
2046180	2049700	And this is the second argument of this function.
2049700	2054680	So if we are looking at the getNativeSystemInfo,
2054680	2061540	we see that this is actually a pointer to the system infrastructure,
2061540	2064900	which is storing all the system information.
2065620	2072460	So again, we can go to the function above.
2072460	2077100	And we can find the second argument here.
2077100	2083580	And we can also rename it to something like systemInfo or whatever you like.
2084680	2090600	As far as this is a stack variable, which is pointing to a structure,
2091060	2101600	we can also do some housekeeping and quickly assign the right structure to it.
2101920	2110680	So that makes it a little bit easier when we are proceeding the analysis to see what's going on.
2110680	2116540	So here we can see that here is actually a comparison between the number of processors
2117400	2123980	and three. With a closer look, we see that if the number of processors
2124800	2129640	of the machine where the sample is running on is smaller than three, then
2133280	2138320	we are just printing out a likely virtual machine detected.
2138320	2145120	So if it has two or less processors, the sample assumes that it is running on a virtual machine.
2145200	2149600	If it is more than two processors, it is returning zero.
2150260	2159600	And again, if we go one level up, we can see here that it is comparing EAX.
2159660	2167320	And only if it is zero, then it is proceeding with the rest of the malware code.
2167320	2169740	If not, it is just exiting.
2172400	2181460	Let's rename the function quickly to something like VMCheck and let's proceed analyzing.
2181940	2187200	So of course, we are also interested in the rest of the code. And to make sure that we can
2187840	2195460	execute it on a virtual machine, we can just toggle the EFlex like you have seen before.
2195460	2200520	In this case, it's a jump zero, so the zero flags are fine.
2200740	2204700	So let's run the trace again and wait for the results.
2214010	2221710	Okay, so I've cheated now a little bit and fast forwarded the video. We run into a timeout.
2221710	2230490	So we are seeing this warning message here. And it is telling us that the response from
2230490	2238470	the DDR server took too long. By default, the plugin waits for 30 seconds to get the results
2238470	2246170	from the DDR server, the trace for example. And if you like, you can change this behavior here
2247030	2254930	under API timeout. You can increase the timeout, for example, to 60 seconds or to 100 seconds or
2254930	2262790	whatever you think works. And then the plugin waits for a longer time. So you've seen earlier
2262790	2269330	that you can also configure the number of instructions, for example, which are supposed
2269330	2277510	to be analyzed. And you can play with these two values a little bit. Of course, if you're
2277510	2284350	increasing the number of instructions, much more data will be collected. And the files which are
2284350	2293250	going to be exchanged are also much bigger. So sometimes it helps to increase the timeout to
2293250	2300070	do these kind of long traces. But nevertheless, make sure that you're not
2303210	2309990	increasing the number of instructions to a too high value. Keep always in mind that it is also
2309990	2321630	increasing the file size of the data which is collected. So coming back here to our issue
2321630	2332890	that it timed out. We can, for example, now look over to the server side and we can check if there
2332890	2339230	was some internal error. For example, there could be a bug inside of DDR which caused a crash, for
2339230	2348230	example. Or there could be some other reason. A super endless loop or whatever. And a sleeper,
2348230	2355810	whatever. And we see here that the analyzers run for 60 seconds. So it seems to be that it was
2355810	2366090	successfully executed. When we are now going back to IDA, we can proceed with the analyzers
2366090	2373130	of the malware to get an idea about what happened. And usually you would now check these
2373130	2379770	instructions what's happening. Of course, I'm not doing that in detail here in the demo.
2380150	2388630	And I know the result and the reason for the timeout in this case is a sleep timer.
2388630	2397830	So you have a sleep timer here which is actually waiting for 60 seconds. And of course that is more
2397830	2405310	than the 30 seconds. And we haven't reached the maximum number of instructions at that point
2405310	2413450	yet. So the DDR server side is still trying to analyze the sample. But there are no new
2413450	2424370	instructions before this sleep is not over. So this means that the analyzers are still
2424370	2433310	going on the server side. But the plugin runs into the 30 seconds timeout.
2433450	2441710	So we could now increase the timeout, for example, and just wait for a little bit longer. Or again,
2441710	2452150	we can just here knob out these instructions and run it again. I don't like to wait, so I prefer
2453050	2461210	using the knob out functionality. And now we are running the trace again.
2462690	2472550	And now it should be a little bit quicker. So light trace done. And now we can clear
2473210	2482390	the old highlighted instructions, clear highlighted instructions. And we can highlight it again. And
2482390	2490150	now we can see the new path with all our patches which we have applied. Now you see that we have
2490150	2499130	manipulated the VM check here, even if it has detected the VMware. Nevertheless, we toggle the
2499130	2514350	E-flag here and we are going this way. And now it is checking here if its name is evilmalware.exe.
2515090	2525690	And if that is not the case, then the sample is going this way. And a quick summary of what's
2525690	2537090	happening here is it is copying itself over to the temp folder. And then finally here, after the sleep,
2538030	2551450	it is creating the process and starting another instance of itself just from this other directory.
2551770	2561850	So this is the reason why we are seeing that we are reaching here this exit call. And the sample
2561850	2570010	seems to be... or the execution of the sample seems to be stopped at that point.
2570670	2578730	In reality, it has started the new instance. And the new instance is running under this name.
2578730	2587550	So it will now go this path and will proceed to execute the rest of the code.
2588410	2593310	This should be enough for this sample. So let's move on to the next one.
2593310	2598570	Actually, one which we found during a recent apt-temp campaign.
2599590	2608970	It is an executable which looks like an XML file. But as you know, if you run that on the command
2608970	2616350	line, it will execute it like any other normal executable. So to get an overview about what it
2616350	2625830	is doing, as usual, we are just running a quick light trace with DDR. And when we are moving over
2625830	2633410	to DDR, we suddenly see... oops, what that? The window disappeared. So it seems to be that
2634030	2641910	maybe the process was killed or something like that. Interesting. So we are moving back to IDA.
2641910	2650490	And we suddenly see that the light trace was nevertheless successfully executed.
2650770	2655910	So it seems to be that the DDR process is still running in the background.
2656530	2664730	So what's going on here? To get an idea, it's always a good idea to check the API calls which
2664730	2671370	were executed. And when we are looking at those, we see that there's a couple of initialization
2671370	2682170	going on. And stuff like rebuilding the IRT, for example. A lot of get process address calls.
2682530	2690810	And after that, we suddenly see, oh, there's a show window API call. That looks interesting,
2690810	2697830	because with show window, you can manipulate the window. And when we are looking into the
2697830	2708270	disassembly, we see that it is using get console window to get the handle of its own window. And
2708270	2716830	then it is executing show window. And show window is using ESI for the command show parameter.
2717110	2726150	And ESI is cleared right before. So we can be pretty sure that ESI is zero in this case.
2726150	2730990	But even if it would be a more complex function in a different sample, for example,
2730990	2739270	of course, we can always use DDR to get an idea about what this value is. Here in our case,
2739270	2748890	zeros, obviously. So it is handing over a zero to show window. And if we are having a closer look
2748890	2758530	to the show window function, we see that the command show parameter is offering a couple of
2758530	2768950	different options. And if it is zero, it is just hiding the window from the desktop. So we have
2768950	2779430	solved the issue why the command window suddenly disappeared. It was not killed. It was just moved
2779430	2787450	into the background. So this is one of the examples how you can pretty quickly analyze
2790110	2794710	what's actually happening with your sample.
2795870	2802730	And now you could either leave it like it is in this case, because it doesn't hurt. Or if you
2802730	2809890	still want to see the window, you just go ahead and you kill these instructions, because you
2809890	2816570	don't need them for anything else. You can just knock them out,
2816570	2828330	about mark instructions. And then we are restoring the snapshot on the
2829710	2839870	on the other side, on the DDR server side. And once it is restored, we can just run the sample again.
2841410	2843890	Just do a glide trace again.
2847470	2854390	And now we can see that it is running normally like before, but it is not
2854930	2860020	hiding the window anymore, because we have knocked out these instructions.
2860730	2866020	And we are done. And we can proceed with our analysis.
2871480	2877080	Back to the presentation. Another special case which I would like to talk about is if you
2877080	2883140	want to analyze the sample in an air-gapped environment. So for example, if the sample is
2883140	2890640	doing excessive anti-VMware checks, or if you have to disable the networking for any reason,
2890640	2896500	there are probably many cases why you want to analyze the sample on an air-gapped system.
2896500	2904460	You can do that because the engine of DDR is implemented in a way that it is a command line
2904460	2912480	tool. And it is heavily leveraging the DynamoRIO framework to do all the instrumentation.
2912660	2919380	So at the end, the DDR server script is just executing this command line tool to
2920340	2930600	inject the DDR DLL into the sample. The DDR DLL is the engine which is doing all the analysis,
2930600	2938580	which is saving all the traces and the registers and so on. And if you're running this command
2938580	2949520	tool via drun-cclient-dll and the sample-to-instrument, you will get a JSON file back.
2949520	2955500	Or actually, you're getting two JSON files back, one for the instruction trace and one
2955500	2964040	for the API trace. These JSON files are looking like this. So they have all the
2964040	2972480	information per instruction in it. So all the registers, all the values of the registers
2973440	2983760	at the point of the instruction, the E-flex, the disassembly, etc., plus the memory location,
2983760	2990880	which might be interesting, and so on. And this is a JSON file which is getting transferred over
2990880	2999940	to the IDA side, which is the IDA plugin reading to fill in its data structures.
2999940	3006740	And with this file, you can then use the plugin like you have seen before.
3007760	3014940	So you've seen earlier in the command that you have to hand over a configuration file.
3014940	3023080	You will find in the docs directory of the GitHub repository a sample configuration file,
3023080	3029460	which is heavily commented and gives you an idea about what kind of commands you can
3030140	3037560	write into this configuration file. We will see in the demo, you can also use the output of the
3037560	3044900	DDR server script to get an idea about what's going on and what kind of values you can use.
3044940	3051920	So for example, you can just generate a certain command via the plugin and then you can check the
3051920	3057500	generated configuration. But again, we will see that later on in the demo.
3059580	3068520	So talking about the demo, let's have a look at it and see how that looks on the command line.
3074330	3080890	So when you are running the command line tool the first time, you can cheat a little bit by
3080890	3089050	looking at the server output. The DDR server is printing out the command which it is actually
3089050	3095930	executing. And this is the command and the configuration which belongs to the command,
3095930	3104470	which was automatically generated by the IDA plugin. So you can start with using the GUI
3104470	3113010	and then you can have a look at the configuration file in the command line. And this gives you
3113010	3119870	probably a good idea how these things are actually working. And for the details,
3119870	3126170	again, you have the documentation in the docs directory of the GitHub repository.
3127350	3131450	So let's just run this again.
3137330	3146930	And once it is finished, we see that it has written all these trace files to the samples
3146930	3151410	directory. So let's move over to the samples directory.
3154010	3162510	And we see that we have all these generated traces here. But there are also further files
3163070	3171010	like the DDR process trace. And the DDR process trace is a file which is logging all the processes
3171010	3177910	which were started by the sample. And pretty much the same, but for threads, are these threads
3177910	3185930	files. They include the information about which threads the certain processes have started.
3186150	3191950	So if we are looking at the processes file, for example,
3192670	3203930	we see that the original sample has executed a second process, the evilmalware.exe.
3204650	3213230	And DDR is following all the threads and processes which the original sample is creating.
3213450	3220670	So we have seen earlier in IDA the trace which was imported for the main
3221300	3230330	thread and for the main process. We haven't seen the second process in IDA so far, but
3230330	3240090	the trace was generated. So we can go back to IDA and we can import this one and then we have
3240090	3247490	all the instructions which were executed by the process evilmalware.exe, the second instance
3247490	3254510	of the buffertest.exe file. And let me show you how that works.
3255870	3264770	Okay, so we are back in IDA and you hopefully remember the sample which we have looked at
3264770	3273010	earlier. The buffertest.1, the one which was checking if its name was evilmalware.exe.
3273010	3279070	And if that is not the case, it is copying itself to the temp folder and executing itself
3279070	3286790	under this name again. And you remember that we were only following the main process here and
3286790	3294880	we were able to highlight the instructions down to the point where the initial process exited.
3295740	3305240	But of course we are also interested in the second part and what happens with the second
3305240	3311420	instance and what kind of code is the second instance executing. One thing we could do,
3311420	3317060	of course, is we could just manipulate the code again like we've done before,
3317060	3323520	or now we are importing these files which we have just generated.
3324080	3333320	So we can clear the highlighted instructions and we are using the loadddr trace
3334400	3344560	button to go to the directory where we have imported these traces which we've seen earlier.
3344840	3352900	So now I'm interested in the one of evilmalware.exe. So I'm loading this one for the trace
3352900	3361000	commands and I'm loading this one for the API calls.
3362800	3371980	So API calls. So now we have successfully imported these traces, one for the API calls and
3371980	3380500	one for the instructions. And now we can use ddr like we've done it before and you see that
3382120	3389100	the second instance which is running under evilmalware.exe is of course going this path
3389620	3402160	and now we can proceed analyzing these parts and look what it is doing like we've done before.
3403160	3409340	GetSourceValue or whatever helps us to understand what this sample is doing.
3411720	3417620	The last thing which I would like to mention is that you should really keep in mind that
3418420	3426460	it is good practice not to run traces for too many instructions. Keep in mind that
3426460	3430980	stopping at every instruction and collecting all the registers and all the memory informations
3431340	3438280	of course it takes a lot of time and consumes a lot of memory. So it's usually good practice
3438800	3445160	to just mark the basic blocks you are interested in. So for example if we are just interested in
3445160	3451740	the values of these two basic blocks it is usually a good idea to just select them
3451740	3462380	at basic blocks to list and this one select at basic block to list and you can see that
3462380	3471460	it was successful here and then run the trace just for the basic block list.
3473620	3481920	And it is done. That is much faster, you don't have to wait for too long and you're not creating
3481920	3489560	gigabytes of files. Just keep in mind that if you are doing that
3491320	3500880	that you now only have these two basic blocks in the database. So all the others are not traced
3501500	3508440	or not in the database in the moment. Which means that if you try to get a value from here
3509080	3517440	of course you're running into an error. It's not in trace. It can be a little bit confusing
3517440	3523500	in the beginning if you don't think about it but usually you are getting pretty quickly used to
3523500	3531960	that. And now you can analyze the functions which you are actually interested in.
3532720	3538800	GetSourceValue or whatever you are looking for. Okidoki, that's it.
3540220	3547200	So you've seen that DDR is not replacing your brain but nevertheless it speeds up a lot of
3547200	3553050	reversing tasks and it is usually a pretty big help in analyzing malware samples.
3553920	3561420	With this I'm done for today and I'm giving back to the folks from the Blue Team Village.
