tag:blogger.com,1999:blog-71352244507879891522024-03-05T07:54:10.821-08:00My Adventures in Game HackingA blog recording my dive into the world of online game hacking.Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.comBlogger39125tag:blogger.com,1999:blog-7135224450787989152.post-70123496783438710322013-12-22T08:42:00.001-08:002013-12-22T08:45:13.849-08:00From Breaking To MakingI definitely had a lot of fun RE'ing PunkBuster. It was enlightening seeing the types of challenges Game Developers have to cope with to make their games fair. As expected, PunkBuster is totally doing it wrong. Building a system that is modifiable by an attacker will never be safe. Luckily, it appears there is now an alternative. Since the BattleField 4 release, a new kid has arrived on the block and they are doing anti-cheating the proper way. And what is that way? By monitoring actions and results *server side* using statistical and behavioral analysis. If this topic interests you, I highly recommend checking out <a href="http://www.gameblocks.com/faq" target="_blank">Fair Fight's FAQ</a>. So yeah soon cheating will be harder, provided GameBlock's implementation is sound and easy'ish to implement in games. So where does that leave me? Wanting to build my own game obviously.<br />
<br />
Online game development is not easy, it requires a developer to be knowledgeable in a lot of very unique topics.(Of course in 99% of the cases, these topics would be covered by multiple people!)<br />
<br />
<ul>
<li>Art & Design</li>
<li>Physics</li>
<li>Responsive interfaces</li>
<li>Combat & AI</li>
<li>Network Programming</li>
<li>Scaleability</li>
<li>Data structure and management </li>
<li>Security</li>
</ul>
<br />
<br />
I think what interests me the most of all of those above topics is Network Programming. Building a safe, fast, reliable and scaleable network protocol that can handle thousands of concurrent users is an extremely fascinating topic. So I think I will start with that and hope everything else just comes together (wishful thinking).<br />
<br />
Here's my current thought process.<br />
<br />
<ol>
<li>Study current MMO / FPS game's network implementations and code if available.</li>
<li>See if it is possible to exploit WebRTC's <a href="http://www.w3.org/TR/webrtc/#rtcdatachannel" target="_blank">RTCDataChannel</a> to get browsers to send data not peer to peer but get access to the UDP transport to implement a custom game protocol.</li>
<li>Build a custom protocol and server in <a href="http://www.golang.org/" target="_blank">Go</a>.</li>
<li>Build a simple WebGL (Probably using <a href="http://www.threejs.org/" target="_blank">threejs</a> game UI.</li>
</ol>
<br />
<br />
Of course everything depends on #2. So I will be spending the next few days PoC'ing that out. If that fails... well we will see.<br />
<div>
<br /></div>
Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com11tag:blogger.com,1999:blog-7135224450787989152.post-75006818523129562402013-09-14T07:23:00.001-07:002013-09-14T07:23:46.871-07:00Finally published The PunkBuster WikiBet you all thought I was dead right? Well, not really, I had to privatize my research until I felt I had made enough progress to publish. This last week at the <a href="http://www.44con.com/">44con</a> security conference in London I presented my research. All of the work I did had been documented over at github <a href="https://github.com/wirepair/PunkBusterWiki/wiki/">in a private wiki</a> until I could release, which I was finally able to do. So head on over and read up on how it all works :).
Enjoy! Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com3tag:blogger.com,1999:blog-7135224450787989152.post-16172578944112660032012-09-10T07:59:00.003-07:002012-09-10T07:59:48.922-07:00I'm in ur memoryz scannin' yur kodez.So I've been slowly working on hacking my pnkbstrk.sys tracer script. It's going pretty well, much better than I thought it would have. In this post I'm going to explain how I built my script along with some of the 'interesting' things I've seen the driver do.<br />
<br />
Basically I'm tracing the functions I think are important. Out of the five or so that I created breakpoints for, only three really displayed anything of interest so far. One function that calls KeTickCount I could have *sworn* would be called for doing some anti-debugging checks in kernel mode never ended up being called. I guess it is something that is triggered either randomly, or by a PB admin? Anyways, the three which were interesting were; MD5Update, strlen and memcpy. To see them all check out the latest 'testing.py' in my <a href="https://github.com/wirepair/GHAST/tree/master/auto_ghast">auto_ghast</a> github repo. (At least when github comes back up...)<br />
<br />
In the mean time here is the pykd code next to the ida function and windbg result of MD5Update.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2hWKBeb0ZvRnd445R8SgG9oTcgyeNMQcpFJExJQ4brjnlmKWLWmsCyhRgeusKDBxLowLKcIAqfWT5UrjHuq-ZhnopBUfxSEh-mWQpIZIAF3aW_40Z8FttjlD9hF6zMAoNopptAP8S2_Q/s1600/md5_update.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="325" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2hWKBeb0ZvRnd445R8SgG9oTcgyeNMQcpFJExJQ4brjnlmKWLWmsCyhRgeusKDBxLowLKcIAqfWT5UrjHuq-ZhnopBUfxSEh-mWQpIZIAF3aW_40Z8FttjlD9hF6zMAoNopptAP8S2_Q/s400/md5_update.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">MD5Update bp + ida + windbg result</td></tr>
</tbody></table>
You should be able to guess how I got the various addresses by looking at the IDA function call and the pykd code. But just to make sure, I'll explain. First we need to get the RVA of where we will set the initial breakpoint. At first I buggered it up and set my bp at the function entry, which when looking up the address of values by using the offset + ebp, I got the totally wrong address. I needed to set the breakpoint after the function prolog. In this case ee00c373. You'll notice my RVA is 0x6373, this is due to subtracting from the base address, in IDA that would be ee006000 (so ee00c373-ee006000 = 0x6373). But the code will automatically determine the base address by looking up the PnkBstrK.sys driver information when it's loaded. This makes it so there is no need to re-calculate every time the driver is reloaded (which happens to be every time the game is started).<br />
<br />
The first value that's retrieved is the length which we dereference ebp+0x10 to get the value. This ends up being 69 bytes. The second value is the buffer address. Which in IDA you can see as being called arg_buf. This is at ebp+0x0c, for this we don't have a value, but yet another address. So we run loadBytes at the address of arg_buf with our length value and print it out. As you can see in the windbg results this happens to be that mysterious MD5 sum I saw a long time ago. The rest is printing out the <a href="http://wammu.eu/docs/devel/internals/md5_8c_source.html">MD5Context structure</a> which, if you look at the testing.py code you'll see how I extract the various members of the structure.<br />
<br />
So yeah, that's MD5Update all nicely traced :). Next up was strlen. In this particular run, it basically strlen's the same weird md5 value we see in MD5Update.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2ylEZ_BHhVGquEgoouMWVv9inpVYXKhCbXq2X4TVJb1xbNtyppBaeJNtm3prEqa0C70LB82grCjsKClZ9sNr1xI19vvJiNILwqLwzbSLG22E9IA3sfHcAohU1KuA67GJOQLYLQ1q6uFQ/s1600/strlen.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2ylEZ_BHhVGquEgoouMWVv9inpVYXKhCbXq2X4TVJb1xbNtyppBaeJNtm3prEqa0C70LB82grCjsKClZ9sNr1xI19vvJiNILwqLwzbSLG22E9IA3sfHcAohU1KuA67GJOQLYLQ1q6uFQ/s400/strlen.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">strlen doin it's thang</td></tr>
</tbody></table>
Yeah, pretty obvious. Saving the best for last, we have memcpy. This was the most interesting as I saw it basically incrementing through 0x1000 bytes at a time, doing a memcpy *directly* from userland addresses into a kernel address (pretty sure that's a big no-no but whatever), where, I'm sure it's doing some analysis/checks. Check it out:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIoOK6LDQd35GybdUZRrMegxg26_Ved_QM3AYUVr1_bOQObnJCW52v2mSSFBEvmY5hb3Kt3_Yte_eOqaga1gTVQX1QGfdbcZDMW2LHNlqfiOatDS5n_hrAxaznLdFXkwcLzQAzZsC6zPM/s1600/memcpy.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="306" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIoOK6LDQd35GybdUZRrMegxg26_Ved_QM3AYUVr1_bOQObnJCW52v2mSSFBEvmY5hb3Kt3_Yte_eOqaga1gTVQX1QGfdbcZDMW2LHNlqfiOatDS5n_hrAxaznLdFXkwcLzQAzZsC6zPM/s400/memcpy.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">memcpy, now things are starting to get interesting...</td></tr>
</tbody></table>
So yeah I think tracing to see what it does with these blobs of memory after it memcpy's will reveal some very interesting things about PnkBstrK.sys. Until next time!<br />
<br />Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com5tag:blogger.com,1999:blog-7135224450787989152.post-7344701431691527472012-08-23T07:55:00.006-07:002012-08-23T07:55:58.587-07:00Auto GHASTWow crap, I've been slacking. Sorry about that. At the same time, I sort of haven't because I'm happy to release my really really alpha auto ghast tool. This is basically a framework that I will end up building out to trace punkbuster and any other driver I need to analyze. I plan on doing a more formal write up later but I figured some people who are semi-familiar with pykd will appreciate some of the stuff I'm working on :>. Basically the idea is to have a method to set breakpoints with callbacks where I can record various registers, values, structures or whatever else I need over the course of running through the driver. In particular for pnkbstrk.sys I want to record all IOCTLs along with various IRP information. You can sort of see what I'm doing in my 'testing.py' script which I walk through later in this post.<br />
<br />
I've also included a built winxp sys driver which is actually just the generic WinDDK ioctl sample driver + exe. If you use the ioctlapp.exe it will install/load the sioctl.sys driver and call it with 4 different IOCTLs. My auto ghast tool was built by repeatedly running/testing with this.<br />
<br />
Anyways, here's auto ghast in action recording a single breakpoint:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP0pAg_5ajrA9XANnBUq7H5HpP07GkZqLNlLRIP41Ic46roY0yqhN4S2UHrOrp846QinZF4t2cTD0WVuod5kAIE7YY8t3ctDzxRttxsssPKPurTdv55J-nd75aA1WFkQETZI0RonmWVGw/s1600/auto_ghast.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP0pAg_5ajrA9XANnBUq7H5HpP07GkZqLNlLRIP41Ic46roY0yqhN4S2UHrOrp846QinZF4t2cTD0WVuod5kAIE7YY8t3ctDzxRttxsssPKPurTdv55J-nd75aA1WFkQETZI0RonmWVGw/s400/auto_ghast.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">auto ghast automatically setting breakpoints/recording data</td></tr>
</tbody></table>
What's nice is all I need to do is set a breakpoint on driver load then run !py testing.py and it does the following:<br />
<br />
<ol>
<li>It steps into the DriverEntry function</li>
<li>Grabs the DriverObject ptr and creates a custom 'driver' object that we can use in the program.</li>
<li>By calling driver.get_driver_by_address(esp) it will extract the pointer and give us access to the drivers properties</li>
<li>Prints out the base/end/entry addresses</li>
<li>Runs through the entire DriverEntry function</li>
<li>Extracts the IRP_MJ_DEVICE_CONTROL address (driver.get_device_control_address())</li>
<li>Creates a custom breakpoint object that I've designed. Set's up various information to record for the breakpoint when it's callback handler is called</li>
<li>Sets the breakpoint</li>
<li>Runs the program</li>
</ol>
<br />
What's nice about having a custom recorder is that we can extract/work with various registers, memory addresses or whatever we want for each time the breakpoint is hit. I'll fix up the documentation of it later but please consider this VERY ALPHA!<br />
<br />
Finally, thanks to<a href="http://antoxar.blogspot.jp/2011/07/pykdtrace.html" target="_blank"> a blog post about pykdtrace</a> which allowed me to figure out that I needed to return DEBUG_STATUS_GO from my debug handler (was banging my head!) to get the dang thing to continue to run.<br />
<br />
Check out my <a href="https://github.com/wirepair/GHAST/tree/master/auto_ghast" target="_blank">ghast git repo</a> for the code!Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com1tag:blogger.com,1999:blog-7135224450787989152.post-30886895495308968262012-07-26T04:00:00.000-07:002012-07-26T04:00:00.006-07:00Introducing GHAST & Finding PnkBstrK.sys when "lm" failsSo I'm pretty sick of doing stuff manually in WinDBG. Now that I have a decent understanding of how to use pykd (well, mostly anyways...) I'm going to start writing and releasing various scripts that help me automate some of my analysis. I figured I'd make a github git repo for all this code, which I've dubbed <a href="https://github.com/wirepair/GHAST" target="_blank">GHAST</a>; Game Hacking Adventures Scripts & Tools.<br />
<br />
One problem I've been having is that PnkBstrK.sys doesn't show up in the 'lm' output. Not exactly sure why this is but at first I suspected it was removing itself from the PsLoadedModuleList doubly linked list. This is a common rootkit behaviour and I pretty much consider PnkBstrK.sys to be a rootkit at this point. To confirm whether this was true, I wrote a <a href="https://github.com/wirepair/GHAST/blob/master/walk_drivers.py" target="_blank">pykd script</a> to walk the PsLoadedModuleList and print out the name, entry point and base address of all modules. Turns out PnkBstrK.sys hasn't removed itself, but for some reason WinDBG isn't listing it.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxwtEtkmURbUhjmCsTGpckjo6RtE1nQaqTxVECCzvXZKbOBS1LeNV8luHQ9NFopZjhSnnEE19pTttpZyZSHA2r1xSqqDrpiBkqY1yeFVkoDGrc9Q4-gJeaReYzfmMp8h9YyzbSyFcgYbI/s1600/psloadedmodulelist.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxwtEtkmURbUhjmCsTGpckjo6RtE1nQaqTxVECCzvXZKbOBS1LeNV8luHQ9NFopZjhSnnEE19pTttpZyZSHA2r1xSqqDrpiBkqY1yeFVkoDGrc9Q4-gJeaReYzfmMp8h9YyzbSyFcgYbI/s400/psloadedmodulelist.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PnkBstrK.sys in the PsLoadedModuleList, but not 'lm' output.</td></tr>
</tbody></table>
Now that I have at least the base address and driver entry point, I can start to automate setting breakpoints and dumping out argument values. My goal is to be able to trace and record all of my 'interesting' functions that I've RE'd from my static analysis. I'm halfway done but the above issue is affecting pykd as well so I needed an alternative way to find the base/entry addresses. The above code can be found here. Hopefully now I can get my other script to work. Anyways, keep your eye on my github repo as I'll update whenever I finish any scripts.Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com1tag:blogger.com,1999:blog-7135224450787989152.post-6750502195954377402012-07-17T06:25:00.002-07:002012-07-17T06:31:22.401-07:00Constant LoveIf you've been following my journey thus far, you may remember a while back when I first started <a href="http://gamehackingadventures.blogspot.jp/2012/01/bit-of-detour-but.html" target="_blank">I identified third party libraries in use in the target I was RE'ing due to the values of constants</a>. Well today is my lucky day it appears. Well, technically yesterday, but whatever. While poking through some more functions in IDA I noticed a very long string of instructions that appeared to be doing some sort of hashing/crypto. I deduced this due to the fact that there were a lot of shr, shl, or, and, and not instructions in a pretty specific pattern.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCn0f1dZyawyztUms1drLG8-mbTc1-ht5LzcjCvPMiwk-l4x5rEXLviSC7mO5fUbNP44SfZCr1wx05cPZWvQ4sxWsQIqZRcsf8jN7-FV1FenwXsBYN3ieG4qEmlYfkrHDwoa_k3iuKJ8k/s1600/md5_transform_consts.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCn0f1dZyawyztUms1drLG8-mbTc1-ht5LzcjCvPMiwk-l4x5rEXLviSC7mO5fUbNP44SfZCr1wx05cPZWvQ4sxWsQIqZRcsf8jN7-FV1FenwXsBYN3ieG4qEmlYfkrHDwoa_k3iuKJ8k/s320/md5_transform_consts.png" width="201" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Hmm, this looks crypto'y</td></tr>
</tbody></table>
<div>
I took a few of the above constants; 28955B88h 173848AAh 242070DBh 3E423112h and threw them in to Google to see what I could find. </div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzL9XplSGOAEQt-dQBBq6zzAn2d5Cqv4k4AGDFRoYNgj9Le1a0qTrqA33Hf9yOD3OW8EiHxzEO5jQQXts_5gkVAA4NKgH5R2mZm6BG3pkYt5sXYgS8x4UtBinCEPwz5ECQ3nHDnLRuzTY/s1600/google_search_constants.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="303" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzL9XplSGOAEQt-dQBBq6zzAn2d5Cqv4k4AGDFRoYNgj9Le1a0qTrqA33Hf9yOD3OW8EiHxzEO5jQQXts_5gkVAA4NKgH5R2mZm6BG3pkYt5sXYgS8x4UtBinCEPwz5ECQ3nHDnLRuzTY/s320/google_search_constants.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">We have a winner! :></td></tr>
</tbody></table>
<div>
After seeing the reference to MD5 I quickly remembered my <a href="http://gamehackingadventures.blogspot.jp/2012/06/dumping-pnkbstrksys.html" target="_blank">GUID related post</a> where I found two values that appeared to be the stringified versions of two md5 hashes. I highly suspect this function is used to generate that GUID. I'm still doing static analysis at this point, my next post will probably clarify what is going on by setting bp's in the debugger while it runs. So we have md5, awesome. No one codes their own MD5, so I bet myself that I could find the source they used... For that I headed over to <a href="http://www.koders.com/" target="_blank">koders code search</a>. I selected C from the language and converted the hex value (28955B88h) to it's decimal form which is 606105819d.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKthZf85bP-qW48dgSBihV3svDN_-3ig1AHkNPRZdsKhJO6qme24LKZUwcoo6E-wVSi-4cmxS1bsRS8xpRco2NlSjYoF8smNw00FxU69ynSJYuq3xPPMa2JQZqhJ7K1SDugDrIncTIkaE/s1600/koders_const_search_results.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKthZf85bP-qW48dgSBihV3svDN_-3ig1AHkNPRZdsKhJO6qme24LKZUwcoo6E-wVSi-4cmxS1bsRS8xpRco2NlSjYoF8smNw00FxU69ynSJYuq3xPPMa2JQZqhJ7K1SDugDrIncTIkaE/s320/koders_const_search_results.png" width="320" /></a></div>
<div><br /></div>
<div>
md5.c from RSA. Can't get any more obvious than that. By <a href="http://www.koders.com/c/fid624EB7C85965B4BF47B5E44142020DA181C9ED91.aspx?s=606105819#L218" target="_blank">finding the direct source</a>, I was able to re-label four functions that are the assembly versions of the C code. Here are snippits of the asm alongside the C source:</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4gLk4L569xWB2TU-ckZSGQByX-1qiGUWPOc9hBiSSd54HJ3czwhH5DpgzWmqqU24BOYX2UyMEvLfjP-u1iNiT9JpG2oTiky7rKSwq1zK2So6mtgYIH-QJo-r5NgUCcKZBjB_Z5XMYWzY/s1600/md5_init.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="110" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4gLk4L569xWB2TU-ckZSGQByX-1qiGUWPOc9hBiSSd54HJ3czwhH5DpgzWmqqU24BOYX2UyMEvLfjP-u1iNiT9JpG2oTiky7rKSwq1zK2So6mtgYIH-QJo-r5NgUCcKZBjB_Z5XMYWzY/s200/md5_init.png" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">MD5Init</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuHRv8pY5yoHMp5CJroTPimTZjvYtfL8-ZQ2A2FMoEjFEZ3ymsAVx6rdMwcYVkckNnsaztOCQrEUdJGrVRS_Njkji7MAYdyeSkuL_kzHEl6OqF2k1JS8dS0Pn2seanOhmT9o9J09WHP6A/s1600/md5_update.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="121" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuHRv8pY5yoHMp5CJroTPimTZjvYtfL8-ZQ2A2FMoEjFEZ3ymsAVx6rdMwcYVkckNnsaztOCQrEUdJGrVRS_Njkji7MAYdyeSkuL_kzHEl6OqF2k1JS8dS0Pn2seanOhmT9o9J09WHP6A/s200/md5_update.png" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">MD5Update</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHHQ3w9BqPf6ADfbc5vfnHXxFgjsdQQwxwhLMxHeRRy5dpC2ouASrw2Lnqsil6KtkrgJZb1SFqnTU-2mWxjMqqFNomEo8dZuSqf2ONRMxe1C_uFd7P39LRXo4bVTiUWNTYU_doza2N6Js/s1600/md5_transform.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="138" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHHQ3w9BqPf6ADfbc5vfnHXxFgjsdQQwxwhLMxHeRRy5dpC2ouASrw2Lnqsil6KtkrgJZb1SFqnTU-2mWxjMqqFNomEo8dZuSqf2ONRMxe1C_uFd7P39LRXo4bVTiUWNTYU_doza2N6Js/s200/md5_transform.png" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">MD5Transform</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIzIVzpeK7IXnSc_Sg7DDTKSjYLqgZ7ypk2ImdBS4m-dn2-3NlBYXek_z3QDhfMVX6Vka-7hyOVZjNP-c5km3IspRc0hhwDwGEA0GZKexDvhxb4VbM3TZqN4dq2IvtBmPn2bn1duQcxKk/s1600/md5_final.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="115" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIzIVzpeK7IXnSc_Sg7DDTKSjYLqgZ7ypk2ImdBS4m-dn2-3NlBYXek_z3QDhfMVX6Vka-7hyOVZjNP-c5km3IspRc0hhwDwGEA0GZKexDvhxb4VbM3TZqN4dq2IvtBmPn2bn1duQcxKk/s200/md5_final.png" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">MD5Final</td></tr>
</tbody></table>
<div>
So we now have four of the md5 functions accounted for and labeled. But continuing my search, I also noticed another function with some pretty unique looking values. Using the same technique above, I took the 9D2C5680h and 0EFC60000h values and <a href="http://koders.com/cpp/fid7F08A19A74F136536B8C382B377C107125C10AEE.aspx?s=0x9D2C5680" target="_blank">koders searched them</a>. To my surprise it turned out to be the Mersenne Twister algorithm, also known as rand() in some languages :>. So now I have two more functions re-labeled to sgenrand(seed) and genrand().</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0zhu30RbbTfVrVdasyYTTetXW52J3GWivefTCrvblUQkiEhLwzLWHnyQhbuH5Gmpd4GAAs5hhW6MHPbJoysJ7h0kl0naVvGPnx-UYcUh2e7S8XKfxfzuP9Sv65Xv8dllc_V294-nJJ5M/s1600/rand.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0zhu30RbbTfVrVdasyYTTetXW52J3GWivefTCrvblUQkiEhLwzLWHnyQhbuH5Gmpd4GAAs5hhW6MHPbJoysJ7h0kl0naVvGPnx-UYcUh2e7S8XKfxfzuP9Sv65Xv8dllc_V294-nJJ5M/s320/rand.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">rand()? Why thank you, don't mind if I do!</td></tr>
</tbody></table>
<div>
</div>
<div>
Overall, a pretty successful find, took longer to write this post than it did to get everything discovered and re-labeled, but hey that's the price you pay for documentation!</div>
Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com1tag:blogger.com,1999:blog-7135224450787989152.post-19983952469557213262012-07-15T07:41:00.004-07:002012-07-15T07:58:00.304-07:00Scripts, Tools and the IDT.So from my last post I had a <a href="https://twitter.com/iMHLv2" target="_blank">few</a> <a href="https://twitter.com/skier_t" target="_blank">people </a>reach out to me about fixing up dumped modules. Unfortunately, I subscribe heavily to the <a href="http://en.wikipedia.org/wiki/Not_Invented_Here" target="_blank">NIH</a> attitude and ended up writing my own quick python module using the <a href="http://code.google.com/p/pefile/" target="_blank">pefile module</a> (note you can pip install pefile as well). All my script really does is set the PointerToRawData to the VirutalAddress value and writes out the changes to a new file (prefixed by new_).<br />
<br />
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeRDark.css" rel="stylesheet" type="text/css"></link>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shAutoloader.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js" type="text/javascript">
</script>
<script type="text/javascript">
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
</script>
<br />
<pre class="brush: python; ruler: true; first-line: 10; highlight: [2, 4, 6]">import os
import sys
import glob
import argparse
import pefile
def dump_directory(path):
for filename in glob.glob(path+os.sep+"*.sys"):
dump_file(filename)
def dump_file(filename):
print "Fixing up: %s"%filename
try:
pe = pefile.PE(filename)
for section in pe.sections:
print "Updating: %s PointerToRawData 0x%x to"\
" VirtualAddress: 0x%x"%(section.Name,
section.VirtualAddress,
section.PointerToRawData)
# Update the section.PointerToRawData to be equal to
# the VirtualAddress/
section.PointerToRawData = section.VirtualAddress
# write the changes
pe.write(filename='new_'+filename[filename.rindex(os.sep)+1:])
print "new_%s written to disk."%filename
except pefile.PEFormatError, msg:
print "Error %s file is not a PE file? msg: %s"%(filename, msg)
def main():
parser = argparse.ArgumentParser(
description='Fixes up the VirtualAddress of drivers dumped from memory.')
parser.add_argument('--directory',
'-d',
action='store',
help='Directory with *.sys driver files.')
parser.add_argument('--file',
'-f',
action='store',
help='Single file to fix up.')
args = parser.parse_args()
if args.directory is not None:
dump_directory(args.directory)
elif args.file is not None:
dump_file(args.file)
else:
parser.print_help()
if __name__ == '__main__':
main()
</pre>
<br />
If you are curious about the recommendations I got. @skier_t recommended his tool <a href="https://github.com/jbremer/rreat" target="_blank">rreat</a>. The tool from @iMHLv2 was a pretty interesting looking framework/toolset for memory analysis of malware called <a href="http://code.google.com/p/volatility/wiki/CommandReference21#moddump" target="_blank">volatility</a>. I'll definitely play around with their tools more, but for now i'mma write my own junk :>.<br />
<br />
So besides fixing up the image once dumped, I've also been working on looking at the various functions of the driver after it's loaded. I came across two very curious blocks of code. At first, IDA didn't flag them as being functions.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiW3uuo1CWJtv9eoISMtOVVAq6Fi0T5zRSkFkeluYyty-mKhIeXFezhJe3P4v82J4hI6bHWqBUEgspUQmAd7FWz9gtOeX2ystkhmUwybrqBNJoCuX3jDk7t2568AAmCiFRmuwTobpBi8CY/s1600/idt_unfunc.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiW3uuo1CWJtv9eoISMtOVVAq6Fi0T5zRSkFkeluYyty-mKhIeXFezhJe3P4v82J4hI6bHWqBUEgspUQmAd7FWz9gtOeX2ystkhmUwybrqBNJoCuX3jDk7t2568AAmCiFRmuwTobpBi8CY/s320/idt_unfunc.png" width="278" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">IDA listing just the code as is</td></tr>
</tbody></table>
But by selecting the start of the function and hitting P, IDA will define it for us.
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjinIeSFbmmWHVK3kv29xY6Tam43AXSonnoW5x3rgpOeeqfO9l87fYbGFnv0zzTJCKVu8tnvvd-sFr8nfFGRgMONap-2D_h09fXtTuYfdsOmv6CUrJCkVlLYaQQftlqUtZZrXlMCpmhkes/s1600/idt_func.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjinIeSFbmmWHVK3kv29xY6Tam43AXSonnoW5x3rgpOeeqfO9l87fYbGFnv0zzTJCKVu8tnvvd-sFr8nfFGRgMONap-2D_h09fXtTuYfdsOmv6CUrJCkVlLYaQQftlqUtZZrXlMCpmhkes/s320/idt_func.png" width="305" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">woo, we have functions! :></td></tr>
</tbody></table>
You'll notice in the above code the two comments I added. If you are not familiar with the <a href="http://www.penguin.cz/~literakl/intel/s.html#SIDT" target="_blank">SIDT</a> and <a href="http://www.penguin.cz/~literakl/intel/l.html#LIDT" target="_blank">LIDT</a> x86 operands, well they are for storing and loading the Interrupt Descriptor Table. I suggest reading materials (both from phrack) if you want to learn more about the IDT and how they are used for hooking. "<a href="http://www.phrack.org/issues.html?issue=59&id=4#article" target="_blank">Handling Interrupt Descriptor Table for fun and profit</a>" article by kad for a deep technical dive into the IDT and the <a href="http://www.phrack.org/issues.html?issue=65&id=4" target="_blank">IDT hooking article by mxatone and ivanlef0u</a> for a more 'windowsy' look.<br />
<br />
Anyways, it appears that the above disassembly stores the IDT values in memory, does a modification (*notice the mov eax, dword_EE01033C...) then reloads the modified version back into the idt register. When doing run-time analysis I didn't see anything at that address except nulls, so i'm not really sure what the point of it is yet. Keep in mind i'm pretty new to this whole IDT business as well. I tried setting a breakpoint on the two functions which modify the IDT and I can't seem them being called at any point yet. I think I will need to do more work in this area to get a better understanding of it all.<br />
<br />
One thing I did notice however is that I'd like an automated way of inspecting the various interrupt entries. If you love python and you use windbg, you should really take a look at <a href="https://pykd.codeplex.com/" target="_blank">pykd</a>, it's pretty damn awesome. After a few minutes of poking through it's samples I found an <a href="https://pykd.svn.codeplex.com/svn/branch/0.0.x/samples/idt.py" target="_blank">old (non-working) script</a> which read the IDT entries. I had to rewrite most of the sample script to run in the latest version, but it works now. It's pretty simple in that it just loops through the IDT entries, extracts the dispatch address, dispatch code and the symbol name and displays it. Here's the code:<br />
<br />
<pre class="brush: python">from pykd import *
import sys
if __name__ == "__main__":
if isKernelDebugging():
dprintln( "check interrupt handlers...\n" )
idtr = reg( "idtr" )
nt = loadModule( "nt" )
ErrorCount = 0
dprintln("idtr is: %08x"%idtr)
for i in xrange(0, 255):
idtEntry = nt.typedVar("_KIDTENTRY", idtr+i*8)
if idtEntry.Selector == 8:
offset = ( idtEntry.ExtendedOffset * 0x10000 ) + idtEntry.Offset
InterruptHandler = offset
kinterrupt = nt.typedVar("_KINTERRUPT",InterruptHandler)
if InterruptHandler != 0x00:
try:
dprintln("IDT [%02x] InterruptHandler: 0x%08x "\
"DispatchAddress: 0x%08x "\
"KINTERRUPT.DispatchCode 0x%08x"\
" (symbol: %s)"%(i,InterruptHandler,
kinterrupt.DispatchAddress,
kinterrupt.DispatchCode,
findSymbol(InterruptHandler)))
except Exception, msg:
dprintln("IDT [%02x] empty"%i)
else:
dprintln( "we are not debugging the kernel..." )</pre>
<br />
And here's some output from it being run from WinDBG:
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUXQ0c8JgLGiMtkk4zX3gPZQv95Njx5tg9bBXGB7puwso8QhoME-9RuuCQjxM73qmxNPxArT04kxrBBddtnPCWHJSJAGmt19BHIiWwjqrVuCNnrDLIcHD7tY1TYx6a-Y8KvI0U66PIk2A/s1600/idt_dump.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUXQ0c8JgLGiMtkk4zX3gPZQv95Njx5tg9bBXGB7puwso8QhoME-9RuuCQjxM73qmxNPxArT04kxrBBddtnPCWHJSJAGmt19BHIiWwjqrVuCNnrDLIcHD7tY1TYx6a-Y8KvI0U66PIk2A/s320/idt_dump.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">idt_dump.py pykd script, dumpin' some interrupt tables baby!</td></tr>
</tbody></table>
I think I'm going to become very well acquainted with pykd, because well, doing this kind of stuff manually kinda sucks.Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com1tag:blogger.com,1999:blog-7135224450787989152.post-24384388604612750132012-07-10T04:13:00.004-07:002012-07-10T04:17:38.710-07:00Dumping PnkBstrK.sys Part 2: Fixing it up!You may remember from my <a href="http://gamehackingadventures.blogspot.jp/2012/06/dumping-pnkbstrksys.html" target="_blank">last post</a> that I was able to dump PnkBstrK.sys from memory but it "looked weird". As in the addresses, even after I rebased the image in IDA to make them look right, were showing up incorrectly. After a bit of work I've figured out not only why but also how to get a module/driver/dll that was dumped from memory to "look right" in IDA.<br />
<br />
You may remember from the <a href="http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&ved=0CKAEEBYwAg&url=http%3A%2F%2Fdownload.microsoft.com%2Fdownload%2F9%2Fc%2F5%2F9c5b2167-8017-4bae-9fde-d599bac8184a%2Fpecoff_v8.docx&ei=HQn8T_ZGguaYBZ-XhKoF&usg=AFQjCNGbwQLCyvU7hJvSRm5fAW1_h9WBog&sig2=RM1OzSo9VJZwnLSzGHLYhg" target="_blank">PECOFF specification</a> that the sections of a PE file have some meta-data associated with them. In particular the IMAGE_SECTION_HEADER. This section has the name, the VirtualSize, address of the section in the image as well as the address of where it will be when the image loads, also known as the VirtualAddress. This is the important part. Because what is on disk versus what is loaded into memory is quite different due to section alignment. Here's what the files look like side-by-side in 010editor.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfhufKA_sdjQkypi9ko9Vv4GQtYl2NS_EvulGr4nVP4kJmba9jwPSD1jSiWcVzkbW-d5kqqWdN63Da7gV0iXC5xO7b8uyYA3n2NgA8uJKRm-i2latU4jww1i6tINeP2ASyeW-5n3izh4w/s1600/file_differences.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfhufKA_sdjQkypi9ko9Vv4GQtYl2NS_EvulGr4nVP4kJmba9jwPSD1jSiWcVzkbW-d5kqqWdN63Da7gV0iXC5xO7b8uyYA3n2NgA8uJKRm-i2latU4jww1i6tINeP2ASyeW-5n3izh4w/s400/file_differences.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The difference between the file from disk (left) and the one dumped from memory (right)</td></tr>
</tbody></table>
You'll notice in the above image there's a large section of null bytes that doesn't exist in the file from disk. This is due to the value of the VirtualAddress section of the PE file for each section. It basically is aligned at 0x1000 so it injects a bunch of null bytes by the loader. If you attempt to load the file as is into IDA Pro you'll get something that looks like the below image.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhroff5W11S8ZSTpDxLkwobzpjvQnxCmlSUUJ7IdfpSmCiGeP0KSa22M6USmLELlWfC7TdzWhUCv5X8qWF_WrGkp2N6eDu4gJcel5deJE-OnXXLl-kD0G2CSBml01O82ZsbuG_5rwCWOuI/s1600/ida_wrong_from_dump.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhroff5W11S8ZSTpDxLkwobzpjvQnxCmlSUUJ7IdfpSmCiGeP0KSa22M6USmLELlWfC7TdzWhUCv5X8qWF_WrGkp2N6eDu4gJcel5deJE-OnXXLl-kD0G2CSBml01O82ZsbuG_5rwCWOuI/s400/ida_wrong_from_dump.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The file that was dumped from memory, rebased, but the DriverEntry is totally wrong.</td></tr>
</tbody></table>
When I first loaded it, the DriverEntry point was totally off. That's because IDA Pro is reading the PointerToRawData value of the PE file metadata struct and assuming that the entry point is where it says it is: at 0x400 in the case of the .text section. This of course is wrong because the dump from memory was aligned differently (adding about 0xc00 of null bytes). With that mystery finally solved (after much head banging, I assure you.) I fixed the PointerToRawData values for each section in 010editor.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB2EzYpu_eXR0MJDvEvb94S6kWbgC9wxHSxtYfZHXmgW05MuIiA3hFhw5W6Cj7mUftpSP_IL7q8anCSpOknj8LHxHyg2QhtsOHqZdBQEHomXfXQxlx2XJTBo9SLsiK93C3Qs-CP12qm4o/s1600/driver_fixed_up.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB2EzYpu_eXR0MJDvEvb94S6kWbgC9wxHSxtYfZHXmgW05MuIiA3hFhw5W6Cj7mUftpSP_IL7q8anCSpOknj8LHxHyg2QhtsOHqZdBQEHomXfXQxlx2XJTBo9SLsiK93C3Qs-CP12qm4o/s400/driver_fixed_up.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Fixing the values for each section for (updating PointerToRawData values)</td></tr>
</tbody></table>
I then attempted to reload the dumped driver into IDA for analysis again. At first I tried to rebase on load (again selecting the "Manual Load" and "Load resources" check boxes) but that turned out to be incorrect as well, as you can see below.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_U8-gfZDIRjpcl2bMDEGhMTKr3Vf_JR5XNjXVlSYL9nLcWLNd4WQFV1lgWvmwwt1Z7zqnb26jM83JtOdAkkKrvmQB25PpU86NBEQebTFYOKUsOcD8EGveop7BTvIzvkegNfuprMsJAKQ/s1600/ida_fixed_address_but_wrong_data.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_U8-gfZDIRjpcl2bMDEGhMTKr3Vf_JR5XNjXVlSYL9nLcWLNd4WQFV1lgWvmwwt1Z7zqnb26jM83JtOdAkkKrvmQB25PpU86NBEQebTFYOKUsOcD8EGveop7BTvIzvkegNfuprMsJAKQ/s400/ida_fixed_address_but_wrong_data.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Looks "ok" but some offsets are pointing to the wrong place!</td></tr>
</tbody></table>
This was annoying as I wasn't really sure how to fix this problem. After mucking around for a while in IDA Pro's rebasing abilities (Edit -> Segments -> Rebase program...) I found if I unchecked the 'Rebase the whole program' I'd get a proper load with all offsets pointing to the right part of the PE file.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI0_8CCQPOmgMnPoOu8Kv-xd8JZ0HHMU7IqZ4BCtfdPnGtx3S-vei1z2GuvBBQ7NCeZvzz0fT0x0-2KHPfVgR1hhbGmD8HIYUxSunaIYwu95GwE64Aco1JkOf5I2wRZ8UrmGk1YUuJzwA/s1600/rebase_but_not_whole_image.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI0_8CCQPOmgMnPoOu8Kv-xd8JZ0HHMU7IqZ4BCtfdPnGtx3S-vei1z2GuvBBQ7NCeZvzz0fT0x0-2KHPfVgR1hhbGmD8HIYUxSunaIYwu95GwE64Aco1JkOf5I2wRZ8UrmGk1YUuJzwA/s1600/rebase_but_not_whole_image.png" /></a></div>
<br />
After all that, I finally got the driver dumped from memory to look like the one extracted from the disk.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnuAM0eUEmQYyDEX9wA8PNkpnzJLHGX9m3o88VYcJsDnA0PBo93WbDCJ6RS3L6HKispxvTDYUz3Z9irL3_IvxXELr9nXa7gQynPUHxyisJPWOGR_nM7aFdksfIsgsYVsOsp3wUbLldyUI/s1600/fixed_dumped_image.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnuAM0eUEmQYyDEX9wA8PNkpnzJLHGX9m3o88VYcJsDnA0PBo93WbDCJ6RS3L6HKispxvTDYUz3Z9irL3_IvxXELr9nXa7gQynPUHxyisJPWOGR_nM7aFdksfIsgsYVsOsp3wUbLldyUI/s400/fixed_dumped_image.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The image with all sections correctly resolved and displayed.</td></tr>
</tbody></table>
And that's pretty much it! Now I know how to dump drivers directly from memory and fix them up to be able to analyze with IDA Pro easier. Hope this saves someone the headache!<br />
<br />Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com0tag:blogger.com,1999:blog-7135224450787989152.post-33743832043157676432012-06-26T06:33:00.002-07:002012-06-26T06:33:18.951-07:00Dumping PnkBstrK.sysSo I finally had a few hours to sit down and muck around in driver land tonight. I learned a few useful things about WinDBG which I kind of which I had known before. This reminds me I should probably read <a href="http://windbg.info/download/doc/pdf/WinDbg_A_to_Z_color.pdf" target="_blank">WinDBG A-to-Z</a> from back to front (or front to back, sheash I've been in Japan too long) at some point.<br />
<br />
Once again I started from the beginning and traced through the first IOCTL coming in. I tried to look for any sort of patterns but again my boredum got the best of me and I kind of gave up. One thing I know is that it is occuring in some sort of loop. I set a break point on the below address because it jumped back to this point a number of times in the code.<br />
<span style="font-family: 'Courier New', Courier, monospace;">.reloc:EE05BB4E lodsb</span><br />
<br />
For those who aren't aware, <span style="font-family: 'Courier New', Courier, monospace;">lodsb </span>basically will take a byte out of <span style="font-family: 'Courier New', Courier, monospace;">ds:esi</span> and store it in <span style="font-family: 'Courier New', Courier, monospace;">al</span> (because we're doing a Load Store Byte). It then increments or decrements <span style="font-family: 'Courier New', Courier, monospace;">esi</span> depending on the <span style="font-family: 'Courier New', Courier, monospace;">df</span> (Direction Flag). By looking at the following code, sure enough <span style="font-family: 'Courier New', Courier, monospace;">eax</span> appears to be a register of importance. One thing I realized I *should* have done, and probably will do once I get some more free time is to totally disregard all the stupid register operations that are going on in this loop and concentrate on one important factor.<br />
<br />
When do the values of registers get *written* to locations in memory? This is a very important operation because this is what will give away what it is doing. I need to see if it's writing to the driver itself? (self modification) or writing to some objects in memory, or doing something else crazy. So this is really where I should have concentrated my efforts better. Instead I was 'getting a feel for it' also known as 'not having a fucking clue what I'm doing'.<br />
<br />
So I set a breakpoint at the <span style="font-family: 'Courier New', Courier, monospace;">lodsb</span> operation in the <span style="font-family: 'Courier New', Courier, monospace;">.reloc</span> section to print out what exactly <span style="font-family: 'Courier New', Courier, monospace;">esi</span> was pointing to. After a few bagillion operations I got a nice table of what byte it was pulling from <span style="font-family: 'Courier New', Courier, monospace;">esi</span> and storing in <span style="font-family: 'Courier New', Courier, monospace;">al</span>.<br />
The command I ran was:<br />
<span style="font-family: 'Courier New', Courier, monospace;">bp ee05e11d ".printf \"esi: %08x ds:esi: %08x\r\n\",esi,by(@esi); g"</span><br />
<br />
This basically sets a break point and tells it to call the printf function displaying both what <span style="font-family: 'Courier New', Courier, monospace;">esi</span> is, and the low-order byte that <span style="font-family: 'Courier New', Courier, monospace;">esi</span> points to (note the '<span style="font-family: 'Courier New', Courier, monospace;">by</span>()' function). Then it tells it to continue running. So I got this enormous table which, is pretty friggen useless to me. While I'm sure if I had time I could script something up to recreate exactly what it is doing, I still hadn't looked at what it's doing with the value once it got into the <span style="font-family: 'Courier New', Courier, monospace;">al</span> register.<br />
<br />
<br />
So even though I am pretty tired of looking at this loop I will need to go back to it and look for any when registers are dereferenced or direct memory locations are referenced for <span style="font-family: 'Courier New', Courier, monospace;">mov</span> or write operations. So I can see what it's modifying. This shouldn't be too hard I think, because from what I could tell it wasn't modifying the loop itself, just other parts of the driver.<br />
<br />
<br />
So to do something a bit different I decided that maybe I should just dump the driver's memory while it's running during various IOCTLs and see if I can see any major changes. After a bit of searching I found out you can dump arbitrary memory by using the .<span style="font-family: 'Courier New', Courier, monospace;">writemem</span> command. This takes addresses/ranges and will spit out the resultant bytes to a file. In my case I ran:<br />
<span style="font-family: 'Courier New', Courier, monospace;">.writemem c:\temp\pnkbstrk_dump_ioctl1.sys 0xEE050000 0xEE073FF6</span> a few times with varying filename parameter values. The 0xee05000 is of course the base address and 0xee073ff6 is the end of the file.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjagXEZPUUmG84nin_fAsN11ZPbvb9KxqtYihnR1kP7JDRWXNhL3qFdSJgXZH2EDas8nUaOCluprborLVjPyR3EiF-rsthBPA3XEA2kVdoyBORiJQgus02Q5x7uTMWcTSgGtyKG3lJplvs/s1600/writemem.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjagXEZPUUmG84nin_fAsN11ZPbvb9KxqtYihnR1kP7JDRWXNhL3qFdSJgXZH2EDas8nUaOCluprborLVjPyR3EiF-rsthBPA3XEA2kVdoyBORiJQgus02Q5x7uTMWcTSgGtyKG3lJplvs/s400/writemem.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">i'm in ur memory, dumpin' ur codes.</td></tr>
</tbody></table>
So now I have three new driver files to look at. Oddly enough they look very different from the one from on disk and I'm not entirely sure why, but there's enough similarity in them to lead me to believe it's just what is in memory, so whatever. For example when the first IOCTL is called the DriverEntry function looks waaaaaaaaaay different then the one I'm working with in IDA (pulled from disk). Even though, I think, none of the self modification code has been called yet? If someone could explain how the hell this happened I'd appreciate it :>.<br />
<br />
Anyways, the most striking difference I found is the relocation table/fix up code that I RE'd a while back. You may remember it was a series of 1000xxxx values that get rewritten to include the real address. Anyways here's what they look like side by side after the first IOCTL has been called.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrccFFpN9fqD6OEjFqIJqNZaxvCcqXs4TuiA2MAKkeUrYlv95N0TQdUlcbO-naD8AB2cBhUaCb7jGTSTRr5fP66esuVGf0JlCkyKkpZGM3d7Zx5NNT7dlUZVofa1Gfz_8XdXqHV1Ckk2w/s1600/symbol_names.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrccFFpN9fqD6OEjFqIJqNZaxvCcqXs4TuiA2MAKkeUrYlv95N0TQdUlcbO-naD8AB2cBhUaCb7jGTSTRr5fP66esuVGf0JlCkyKkpZGM3d7Zx5NNT7dlUZVofa1Gfz_8XdXqHV1Ckk2w/s400/symbol_names.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">yehp, symbol names.</td></tr>
</tbody></table>
The other thing I noticed was another area around this section of the driver that contained a very curious ID. So curious that I think it might be my GUID, the one that EvenBalance/PunkBuster use to global shit ban people. This is the first time I've seen it so I'm totally jumping to conclusions on that. Anyways, since that *may* give away who the hell I am, i'mma muck with it in the image below:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKyKsFPgpHIXd7npA4CBA3cGHD3-SYExVuFmL4-OqhzBU-jIJ1wApMlSsgXUN_GVud71aA96EUSzLE0wVUIVc-00pYSwUbhVpkuuGGJlot-Vxdc9CmQK24h1SH6iONZEhyphenhyphenWfsq2jTYUGQ/s1600/possible_pb_guid.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="115" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKyKsFPgpHIXd7npA4CBA3cGHD3-SYExVuFmL4-OqhzBU-jIJ1wApMlSsgXUN_GVud71aA96EUSzLE0wVUIVc-00pYSwUbhVpkuuGGJlot-Vxdc9CmQK24h1SH6iONZEhyphenhyphenWfsq2jTYUGQ/s320/possible_pb_guid.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">My guid? Maybe? Notice the BFP4F in the middle of it...</td></tr>
</tbody></table>
It's a 69 byte long string with BFP4F in the middle of it. The first section (before the BFP4F string) is 24 bytes, the second section (after the BFP4F) is 40 bytes. Both sections are stringified hex strings, as in a string representation of the hex bytes. So yeah, maybe two 32 byte md5 hashes with a BFP4F thrown in the middle to split them up? I dunno... yet!<br />
<br />
<br />
<br />
<br />
<br />Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com0tag:blogger.com,1999:blog-7135224450787989152.post-33209250037423164202012-06-07T03:10:00.002-07:002012-06-07T03:10:43.291-07:00Tedious Boring Work (Obfuscation 1, Me 0)I really do want to be posting more, and exploring more and learning more. But right now I'm stuck in state of tedium. The past few attempts at looking at PnkBstrK.sys have left me pretty bored. Right now the majority of the code is doing some sort of silly obfuscation and is just fixing up addresses and data. After the first IOCTL is sent to the driver, the IOCTL instructs the driver to fix up some table of addresses. In IDA we can see this table of pointers in it's base address form.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizBjH2NG0YymBa5oNJLZ57ibEsg1cf8BarPRfPsfRWy-ai57kxO9fJc8RjZOl7g-8_qjqCrYhNZGkGplcI6QZhVJkkzCMitNMiTYeYwI0bI9RujuwCEIrAMCmJUHKAq6CjnYZrq-XWGig/s1600/base_addr_table.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizBjH2NG0YymBa5oNJLZ57ibEsg1cf8BarPRfPsfRWy-ai57kxO9fJc8RjZOl7g-8_qjqCrYhNZGkGplcI6QZhVJkkzCMitNMiTYeYwI0bI9RujuwCEIrAMCmJUHKAq6CjnYZrq-XWGig/s400/base_addr_table.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A table of pointers that are to be 'rebased' during execution</td></tr>
</tbody></table>
You can see from my comments in the above code that various registers contain the address of the driver in memory, which in a below function are used to recalculate the table and update it to point to where the driver is loaded for the current execution run. This table, when all is said it is updated to look like:<br />
<br />
<br />
ee05b844 ee05e046<br />
ee05b848 ee05c997<br />
ee05b84c ee05d719<br />
ee05b850 ee05bc4d<br />
ee05b854 ee05f5f1<br />
...<br />
ee05bad0 ee05c842<br />
ee05bad4 ee05c049<br />
ee05bad8 ee05f3e4<br />
ee05badc ee05eff3<br />
ee05bae0 ee05cc3c<br />
<br />
While that part of the code is easy to understand, what isn't easy is the next part.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh256Yc0Cyo7NycTzjxwrv7edXf9IvSX3S4_Tkrh7xoRf3Kxwwua6vHflo1egmZ0AhXU4MNk-NWThAYBUmEdW9QgS8IPWocSaimR9DdUXqFSymMXFrk_1Llweq1OLodZg6Xj6Hnrnmle1U/s1600/tedious_addr.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="153" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh256Yc0Cyo7NycTzjxwrv7edXf9IvSX3S4_Tkrh7xoRf3Kxwwua6vHflo1egmZ0AhXU4MNk-NWThAYBUmEdW9QgS8IPWocSaimR9DdUXqFSymMXFrk_1Llweq1OLodZg6Xj6Hnrnmle1U/s400/tedious_addr.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Borrrrrrrrrrrrrrrrrrringgg....</td></tr>
</tbody></table>
The rest appears to just be doing arithmetic to change various addresses both in the stack and in the registers. It's so boring and tedious that I find it hard to walk through more than a few functions at a time before I give up and go do something else.<br />
<br />
I guess, that *would* be the entire point of obfuscation :>. However, I don't plan on giving up, but forgive me this might take a bit longer because, well, it's boring as shit. Someday when I have more free time (right now i'm clocking in about 1-2 hours a week looking at this) I'll sit down and run through the entire process to see if there are any patterns I can extract on what it is doing from a more high level view point.<br />
<br />
<br />Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com0tag:blogger.com,1999:blog-7135224450787989152.post-55920042081634631562012-05-25T18:06:00.001-07:002012-05-25T18:08:28.440-07:00Manually Loading Segments in IDAIt's been a while since I posted. Mainly because I took a two week trip back to America and totally forgot to copy over IDA. Now that I'm back and my jetlag has subsided a bit, I'd like to post a real quick update on how to get IDA to load that 'hidden' data from PnkBstrK.sys. While the '.reloc' section wasn't marked in the PE, the hidden data, according to IDA is simply the .reloc section. Apparently, to get it to load you need to do a Manual Load when you first do your analysis. If someone knows how to get IDA to re-analyze the file and not lose your comments/symbols that you've added I'm all ears.<br />
<br />
Since I couldn't figure out how to do that, I decided to just reload the file and manually add in my comments again. When you first load a new file you have a number of options to chose from.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3I5p5v1_fBj4RFVJuMUReF9SK_lkgmXLHezpyXsd64OgO1z21jZvryaF0RR93tEP0EnxtaXkdslvHE2JQ9TiAQ_eFlQcf70OR4OzXi7L1TuUF7QNAiZk3g0CfPFM4kRENwpbxhgHkblA/s1600/manual_load.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3I5p5v1_fBj4RFVJuMUReF9SK_lkgmXLHezpyXsd64OgO1z21jZvryaF0RR93tEP0EnxtaXkdslvHE2JQ9TiAQ_eFlQcf70OR4OzXi7L1TuUF7QNAiZk3g0CfPFM4kRENwpbxhgHkblA/s320/manual_load.png" width="290" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Make sure to select 'Load resources' and 'Manual Load'</td></tr>
</tbody></table>
After selecting the Manual load and Load resources check boxes go ahead and click OK. You'll then be asked if you want to specify a new base image (rebase). Since my VM image is locked with the driver loading at EE118000, I decided to set the base image to that so I don't have to do any math when I'm comparing addresses.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF1OAk2QOIDfJ8Z7Oc_1ZD0A8D4UCzypL0MJwe2nnen29DR_UMqKg2WBNhvKlglxeOExf8AD1XBsvlDDLdPe_xqHjDgMg51NuDNXxKAAtRuEdQmezyRFDw7VoX535peyf79683tebx9CE/s1600/rebase.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="156" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF1OAk2QOIDfJ8Z7Oc_1ZD0A8D4UCzypL0MJwe2nnen29DR_UMqKg2WBNhvKlglxeOExf8AD1XBsvlDDLdPe_xqHjDgMg51NuDNXxKAAtRuEdQmezyRFDw7VoX535peyf79683tebx9CE/s320/rebase.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Setting a base address to my VM image's driver location.</td></tr>
</tbody></table>
Finally, the part we really need, is to have IDA ask us which segments we want to add for analysis. You'll notice here that the last one is what we need, the '.reloc' section. Why this isn't done by default I'm not exactly sure, but after loading this you'll be able to see all that extra hidden code that PnkBstrK.sys has. This will make our analysis much easier in the end. <br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgd6tONbQwBnVqyZQ28hW_nYJMrpfOjCf6ERtVBvSUpCSyIwCgH6_pn-udGPQU2N89nWwlZVH3H0_6j9qdWii4ol643Vnm9vnjzKK8meI2CS2PkpINqDrPq5PzEESiw7MSfISCbRT1lfzI/s320/load_segments.png" style="margin-left: auto; margin-right: auto;" width="96" /></td></tr>
<tr><td class="tr-caption" style="text-align: center;">IDA asking us which segments to load.</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: left;">
<span style="margin-left: 1em; margin-right: 1em; text-align: -webkit-auto;">As you can see in the final image, our new IDA window on the left shows the jmp address as going to a valid location.</span></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT0JpOH3pDTTNX1aCWinjL3BIVqMdO4dh38BY8A1Uc9tfvK5ob2wR0pGqcKcVE4wnucX3SMjpancS2ogy30kwAK_ijGUZ5Ycc0knqcmd1qwi-tWZt8Qy4BLEKepWSbz8GRizPQ9eNlDi4/s1600/valid_jmp.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="85" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT0JpOH3pDTTNX1aCWinjL3BIVqMdO4dh38BY8A1Uc9tfvK5ob2wR0pGqcKcVE4wnucX3SMjpancS2ogy30kwAK_ijGUZ5Ycc0knqcmd1qwi-tWZt8Qy4BLEKepWSbz8GRizPQ9eNlDi4/s320/valid_jmp.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Left: Valid analysis with .reloc address, Right: Old version jumping to unknown address</td></tr>
</tbody></table>
That's pretty much it, now I can properly trace all the calls to the code outside of the .text/.data sections that PnkBstrK does.Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com0tag:blogger.com,1999:blog-7135224450787989152.post-1894266426177365682012-04-23T04:27:00.001-07:002012-04-23T04:27:11.628-07:00Sneaky Sneaky... PnkBstrK.sys's hidden code.As you might recall from my last post I'm now in the process of determining what the IOCTLs do. There was however one thing that was really bugging me. I didn't allude to this yet because I figured I was doing something stupid and just didn't understand how the driver's code was being mapped into memory by Windows. It turns out PnkBstrK.sys is doing something a little bit sneaky. Before I get into showing what they are doing, I want to describe the problem.<br />
<br />
When attempting to determine what the IOCTLs are actually doing I was noticing the first IOCTL that was "attempted" was calling a function which after doing some oddness, was jumping into some memory location that wasn't showing up in IDA. The first IOCTL that is seen by our DeviceControlDispatchHandler function is 0x2261c0.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinr9oL1FC2X_wVmC3R-MLaB1cWX1i1Wk3E7vI3ACqPb47lUepppfuwZ2h2AJf0LX9SlxB2PPKhC112eKqjQwshf7FlyT-Okquf9P-Iks7RBsJTzkTLRvAKfEW-xfqp6ecImV7IrK3y3RM/s1600/call.hidden.code.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinr9oL1FC2X_wVmC3R-MLaB1cWX1i1Wk3E7vI3ACqPb47lUepppfuwZ2h2AJf0LX9SlxB2PPKhC112eKqjQwshf7FlyT-Okquf9P-Iks7RBsJTzkTLRvAKfEW-xfqp6ecImV7IrK3y3RM/s400/call.hidden.code.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">First function that is called from the 0x2261c0 IOCTL.</td></tr>
</tbody></table>
This function clears out some addresses and moves the value 0x3f onto the stack. Then jumps into some unknown address.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikmJ2poiMif9GNeuhDqXQhiufF1ONKNAsfLqu4e6T0mSJoiVqONpFNvljL1qVuUf3IzZfr7XkSK__hEPgyyNDaOOjMB-K_AT4td8LaBz86RBiwmtV45X15LMl5B7TBdKvcIJi5tMG6MoQ/s1600/call.unknown.addr.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikmJ2poiMif9GNeuhDqXQhiufF1ONKNAsfLqu4e6T0mSJoiVqONpFNvljL1qVuUf3IzZfr7XkSK__hEPgyyNDaOOjMB-K_AT4td8LaBz86RBiwmtV45X15LMl5B7TBdKvcIJi5tMG6MoQ/s400/call.unknown.addr.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A jmp into an unknown memory address.</td></tr>
</tbody></table>
This is where I was stuck. I had no idea where this memory location was coming from. So I figured they were jumping into a non .text section. If you aren't familiar with the various sections of a PE file I suggest reading the <a href="http://msdn.microsoft.com/library/windows/hardware/gg463125" target="_blank">PECOFF document</a> from Microsoft. So in IDA you can look at the various segments by hitting "Shift+F7" or View->Open Subview->Segments. Here's basically what I saw:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuAL-2ouW8QOwWGYW37vOllB1x2l2ijBXEIJF62X7iQ47NuRR1baYxfzKA-8-ibliOSoo7OjQv9F7hJyPHaR2wy7jIEVhj8twyLbHRVcXq2o2L_yiXSm4UHSJQCylzOWF8x9S8j0GxlVQ/s1600/pnkbstrk.sys.segments.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="187" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuAL-2ouW8QOwWGYW37vOllB1x2l2ijBXEIJF62X7iQ47NuRR1baYxfzKA-8-ibliOSoo7OjQv9F7hJyPHaR2wy7jIEVhj8twyLbHRVcXq2o2L_yiXSm4UHSJQCylzOWF8x9S8j0GxlVQ/s400/pnkbstrk.sys.segments.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PnkBstrK.sys segments</td></tr>
</tbody></table>
You'll notice none of those addresses are within range of our 'unknown' jmp address. Ok so now what? I honestly had no idea. When debugging the driver and that ioctl is called, it jmps to the unknown address but magically a valid code block is there. But how? I can't see any of the data in the segments and I certainly can't see any data in the .text segment. I called shenanigans.<br />
<br />
I totally reset my vmware image thinking that some how during installation it was doing something to create this page in memory without me catching it in time. My first suspicion was that code was being called before the DriverEntry method. I searched all over Microsoft documentation to see if there was any other way of calling a driver besides the DriverEntry function. While I found out there is, it's only if you rename the DriverEntry function to something else (which this driver is not doing).<br />
<br />
So I decided to look at something else. I loaded up PEiD which is a tool for looking at the segments. My thought process here was that they were doing something to trick IDA Pro. Here's what PEiD reports:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5-XmbMURNN1RqSsFOueC0eTnVQWSbtyHRWCfFs90W9Fzv-szthJgLAgUiAcNpznHVFJTsbBE8WccC4hlTnvLad8Vvix_X_bWsXcz5sGUeVyo8C3fN_UGNKHwW6CHMe8glhlZRfMwiJO8/s1600/peid.output.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5-XmbMURNN1RqSsFOueC0eTnVQWSbtyHRWCfFs90W9Fzv-szthJgLAgUiAcNpznHVFJTsbBE8WccC4hlTnvLad8Vvix_X_bWsXcz5sGUeVyo8C3fN_UGNKHwW6CHMe8glhlZRfMwiJO8/s400/peid.output.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PEiD section output</td></tr>
</tbody></table>
OK so, basically the same thing. So I went back to WinDBG to see if there were any other hints. You may remember from a long time ago, one of the methods I use in RE'ing (because I suck at it) is to use surrounding data as possible hints to what the code is doing. In this case I am looking at surrounding data to find hints as to where the code came from. So here's what I see at that address in the data output (instead of looking at the disassembly) of our "unknown" address:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJfuYRCEWXQ0KvNd4saZwxdsNoHorCMH6YUd0lmA9gN2s0borFDAN98V3Eq8JoN7qGU3neMe0jVvqX630nfO84Hzi5m-MZfoBt8JJgg8KWvlIS_Xmlg3KI66DCmmdWqzfC4LyJmIISoLs/s1600/unknown.address.data.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJfuYRCEWXQ0KvNd4saZwxdsNoHorCMH6YUd0lmA9gN2s0borFDAN98V3Eq8JoN7qGU3neMe0jVvqX630nfO84Hzi5m-MZfoBt8JJgg8KWvlIS_Xmlg3KI66DCmmdWqzfC4LyJmIISoLs/s400/unknown.address.data.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The data at our unknown address. Note the VeriSign certificate information</td></tr>
</tbody></table>
OK so that is a pretty good hint. So going back to IDA I searched for the string VeriSign (alt+T to search for text) and guess what. Absolutely nothing. So I had one last thought. Maybe it's not really contained in a valid segment at all, maybe it's contained in the binary and they're doing a hardcoded jmp? So I want to look at the PECOFF structure. For that I use <a href="http://www.sweetscape.com/010editor/" target="_blank">010Editor </a>with the <a href="http://www.sweetscape.com/010editor/templates/files/EXETemplate2.bt" target="_blank">PECOFF template</a>. I load the file, open the template and run the template against PnkBstrK.sys. I notice the following bits of data:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixBGmTYLu19qL_kL-LBwJAL47xgI92iiwbyTNvxF4X_jcqOUMTV9oMLEBPackuOfxUGwxfleied4-g6YLVxvGa6LUqangm5WDW1GA1AOm3iEslfrf5QdMTNAogtJGuRHHeyxLrwz0ozjc/s1600/exetemplate.results.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="61" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixBGmTYLu19qL_kL-LBwJAL47xgI92iiwbyTNvxF4X_jcqOUMTV9oMLEBPackuOfxUGwxfleied4-g6YLVxvGa6LUqangm5WDW1GA1AOm3iEslfrf5QdMTNAogtJGuRHHeyxLrwz0ozjc/s400/exetemplate.results.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Overlay? What the hell is that?</td></tr>
</tbody></table>
So there's this 'overlay' section, and the data?<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_fCpkV0qrDwkQOYatJIensGl96hVKQXnXxCeC4PeaP5HPVrHX_rTswond8qVO0WeBLwmAatvtIDRxBtpFxRSR7q0Eb7_pme0ycIhljvODpsnGf63FiYfl-DfFaY-SsL1B1OFwucnka1Q/s1600/010editor.pnkbstrksys.overlay.data.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_fCpkV0qrDwkQOYatJIensGl96hVKQXnXxCeC4PeaP5HPVrHX_rTswond8qVO0WeBLwmAatvtIDRxBtpFxRSR7q0Eb7_pme0ycIhljvODpsnGf63FiYfl-DfFaY-SsL1B1OFwucnka1Q/s400/010editor.pnkbstrksys.overlay.data.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">There you are! You sneaky bastard!</td></tr>
</tbody></table>
So in the EXE template I looked at how 'overlay' data is generated and I found they simply check:<br />
<br />
<br />
if(max < FileSize()) {<br />
BYTE Overlay[FileSize()-max];<br />
}<br />
<br />
That is all they are doing. PnkBstrK.sys isn't creating a section for it, they're just appending the data which will still get mapped into memory and then they are 'hardcoding' the jmp to the offset into this extra data area. Pretty sneaky.<br />
<br />
It is almost like a magic trick, at first it seems like magic, then you realize you're just an idiot for not knowing how it worked to begin with.<br />
<br />
NOW I can start to figure out what these IOCTLs do :><br />Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com1tag:blogger.com,1999:blog-7135224450787989152.post-20446372981628712572012-04-17T03:33:00.001-07:002012-04-17T03:35:46.879-07:00Kernel Hacking Is Hard (KHIH)Besides totally slacking on game hacking, I have taken the time to read four documents from Microsoft which I felt were important for gaining at least a bit of understanding of this driver craziness.<br />
1. <a href="http://msdn.microsoft.com/en-us/windows/hardware/gg463273" target="_blank">Architecture of the Kernel-Mode Driver Framework</a><br />
2. <a href="http://msdn.microsoft.com/en-us/windows/hardware/gg463314" target="_blank">Architecture of the Windows Driver Foundation</a><br />
3. <a href="http://msdn.microsoft.com/en-us/windows/hardware/gg463271.aspx" target="_blank">I/O Flow and Dispatching in WDF Drivers</a><br />
4. <a href="http://msdn.microsoft.com/en-us/windows/hardware/gg487398" target="_blank">Handling IRPs: What Every Driver Writer Needs to Know</a><br />
<br />
Since I have a little (and I mean very little) understanding of drivers, I do have a bit of a suspicion that the PnkBstrK.sys driver is simply reading in custom IOCTLs and acting upon them. However, I wanted to confirm this. I did a bit of reverse engineering of the PnkBstrK.sys DriverEntry function. You'll notice in my IDA output I renamed a lot of things (and added comments) to make understanding what was going on a bit easier. Remember ';' for adding comments and right click -> rename for renaming labels/functions whatever.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAhG9dGsxva97Ptb7sbIOTnCL9GJwHuSt2T_oF-WOMsf2IFSOaoDh6yQUr7jvTAw-dRZvQ7m3HTYRoxD4MVOaslYzadjxXdQPvnxdiLScuyMm5C111EyZXuhuRGeweurzop5gV8PneyO8/s1600/driverentry_re.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="385" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAhG9dGsxva97Ptb7sbIOTnCL9GJwHuSt2T_oF-WOMsf2IFSOaoDh6yQUr7jvTAw-dRZvQ7m3HTYRoxD4MVOaslYzadjxXdQPvnxdiLScuyMm5C111EyZXuhuRGeweurzop5gV8PneyO8/s640/driverentry_re.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PnkBstrK.sys DriverEntry function.</td></tr>
</tbody></table>
It's a pretty standard setup, loop over and set all IRP handlers to the same function. Except one, you'll notice at .text:10033FB (I renamed DeviceControlDispatchHandler) a function is moved into an offset into the DriverObject structure. Initially when analyzing this, I missed that line and during debugging sessions always ended up going to the same stub dispatch function which did nothing. So what is this special handler? This is actually the dispatch handler that will handle the IRP_MJ_DEVICE_CONTROL "event" or whatever the hell they're called in kernel land. All of the other handlers don't do anything but accept the IRP and pass it on/finish it.<br />
<br />
Later on, you'll notice a call to IoCreateDevice with the "\\device\pnkbstrk" as the device name. Further down in the code a symbolic name "\\DosDevices\\pnkbstrk_link" is also created which the user-mode applications will most likely call. However, I have yet to verify this.<br />
<br />
Which is actually my biggest problem, trying to figure out how user-mode code calls into this driver. After searching around I found a really <a href="http://www.woodmann.com/forum/showthread.php?14561-Had-to-say&p=91470&viewfull=1#post91470" target="_blank">good forum post</a> on how to gain a bit of additional information when debugging drivers. From that post I learned if you are actively debugging PnkBstrK.sys there's a way you can determine what IRP handlers are mapped to. In WinDBG you run "!drvobj PnkBstrK 7" which gives the following output:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwgl6ENdsw-rOclUExwPhThwA-obHgFjuOZo7Kiuq8jjnei2R6eVZCYQP5VMQMn72H9UNl5Eke6RCfaIU2t_wzpGHqcnF2_ayLW1RYu-wwEM54fFilfDkfm6OzBI2Wu7DWvzHW6NRBTDY/s1600/irp_dispatch_table.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwgl6ENdsw-rOclUExwPhThwA-obHgFjuOZo7Kiuq8jjnei2R6eVZCYQP5VMQMn72H9UNl5Eke6RCfaIU2t_wzpGHqcnF2_ayLW1RYu-wwEM54fFilfDkfm6OzBI2Wu7DWvzHW6NRBTDY/s400/irp_dispatch_table.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PnkBstrK.sys IRP dispatch handlers</td></tr>
</tbody></table>
You'll notice they're all set to the same address, except one: [0e] IRP_MJ_DEVICE_CONTROL. This is what I believe the user-mode code calls to interact with this driver. So my next step(s) are to do a bit of analysis of this device control handler function. For that I turn back to IDA.<br />
<br />
Here's what the device control handler function looks like by itself:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiefRMNN6sTgBmbNYThLjxuAX_0M0M38U20YMBujGfhZyV-rQjbcs9M5SN5JaUVSxC5TFikpnnmQ8hIrk6fRrv6nXrRhSFu2aaSqyNBJmB4TREDevD0KGhw-trolgr2VEJozefL0Tdgwww/s1600/device_control_no_comments.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiefRMNN6sTgBmbNYThLjxuAX_0M0M38U20YMBujGfhZyV-rQjbcs9M5SN5JaUVSxC5TFikpnnmQ8hIrk6fRrv6nXrRhSFu2aaSqyNBJmB4TREDevD0KGhw-trolgr2VEJozefL0Tdgwww/s400/device_control_no_comments.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">device control handler function with no comments/names.</td></tr>
</tbody></table>
So that's not really helpful. Again, taken from that above post he suggests including the IRP and IO_STACK_LOCATION structures into the IDA session. This ends up helping a lot. How do you add structures? It's pretty easy, click on the 'structures' tab of your IDA view and hit the 'Insert' key. Next click 'Add standard structure'. Then find the IRP structure (or _IRP).<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHF3s087bKvZHhqhLPXBvAs0SxDzZEyEVaad5Zmvam-Zzd-4BPeUankXl_qE4pmGjcAt4huuotJsnqml4Rhx4ccY_s6L2i0OuD7rjEMyV7VSQbImvgqF6U0PLuJGgmbYvvmocDAJi1yIQ/s1600/ida_add_irp.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHF3s087bKvZHhqhLPXBvAs0SxDzZEyEVaad5Zmvam-Zzd-4BPeUankXl_qE4pmGjcAt4huuotJsnqml4Rhx4ccY_s6L2i0OuD7rjEMyV7VSQbImvgqF6U0PLuJGgmbYvvmocDAJi1yIQ/s400/ida_add_irp.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Adding the IRP structure to IDA</td></tr>
</tbody></table>
Do the same for the IO_STACK_LOCATION structure and go back to the device control dispatch function at .text:10002fC0. Now we can change Irp+60h to [eax+IRP.Tail.Overlay.anonymous_1.anonymous_0] by selecting the 60h part and hitting 'T' and selecting the proper value. Not sure why it's that structure value, but whatever, that's what the dude from the forum said. Three lines below that you'll see a mov eax, [edx+0Ch]. This can be transformed to: IO_STACK_LOCATION.Parameters.DeviceIoControl.IoControlCode which looks a bit more reasonable to me. Here's what I've come up with for this segment of code after doing some initial analysis of it:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiDJKn0KVLv3S1O7TTaO4b55QRZezFVoK5dlvXkvUqjcs27nN4Skm8u5Q5qJVqDDP119mexsLOmbsZXAYdAucdqK0ffXQkvnhEgyEWh-0D_az01It5vpD0kCCfeCAqDN6XXasB-d94Etk/s1600/device_control_comments.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiDJKn0KVLv3S1O7TTaO4b55QRZezFVoK5dlvXkvUqjcs27nN4Skm8u5Q5qJVqDDP119mexsLOmbsZXAYdAucdqK0ffXQkvnhEgyEWh-0D_az01It5vpD0kCCfeCAqDN6XXasB-d94Etk/s400/device_control_comments.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">DeviceControlDispatchHandler with comments.</td></tr>
</tbody></table>
Of course, I've just started doing this reverse engineering so there are two things to keep in mind; I'm not done yet and I could totally be wrong. Trying to figure out what the Irp+60h value pointed to turned out to be challenging for me. I looked through the 'wdm.h' header file and found the _IRP definition but without looking up all it's members, I have no idea what the 0x60h offset points to. Again, the forum post I mention earlier helps clear that up, but I hadn't read it at that point. If you haven't already, I seriously suggest going back to read it.<br />
<br />
*After* reading that post, I tried running the commands he mentioned to see what the structures look like from WinDBG, but it went horribly wrong. Mainly because I wasn't referencing the value correctly.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiArc8SC3_-E9NQsZBy8yE6beTirCKIPFRLPrGufLGZVGKzZPN9GjV8Ym8jwLrg3gi_0RBQ20pNXOHnD14mY8HKq3h9mQMp_0cAkCMw29WIG1iO6FsJ7NMgiLvkhwI5KZFnEwOfi7k4Ffc/s1600/irp_maybe_value.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiArc8SC3_-E9NQsZBy8yE6beTirCKIPFRLPrGufLGZVGKzZPN9GjV8Ym8jwLrg3gi_0RBQ20pNXOHnD14mY8HKq3h9mQMp_0cAkCMw29WIG1iO6FsJ7NMgiLvkhwI5KZFnEwOfi7k4Ffc/s400/irp_maybe_value.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Attempting to display the IRP struct values using the wrong value.</td></tr>
</tbody></table>
Next I waited until ECX got set to the value of the IRP structure and tried again:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga-36Sz0DMjfem4-kLEfR0Cqog_ZOdYyYgs1_TIl6_QS1lqToYWCfZMnbuAZuvbvWAdz8FsRSNeZQTzD8dksNlLYdH-xPZ3SNqdoorVixksaV7uIG4KF3Mp5B51waDhXIz3ls9Yk8EKsY/s1600/io_stack_location.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga-36Sz0DMjfem4-kLEfR0Cqog_ZOdYyYgs1_TIl6_QS1lqToYWCfZMnbuAZuvbvWAdz8FsRSNeZQTzD8dksNlLYdH-xPZ3SNqdoorVixksaV7uIG4KF3Mp5B51waDhXIz3ls9Yk8EKsY/s400/io_stack_location.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">_IRP.Tail (0x40) + CurrentStackLocation (0x20) => 0x60 = IO_STACK_LOCATION (I think?)</td></tr>
</tbody></table>
So this looks 'better' but the 'memory read errors' throughout the structure references makes me think I might be wrong. OH WELL. I'm sure it'll all become clear the more I work with this stuff. <br />
<br />
Of course, next up is reversing what the different IOCTLs actually do. That might take me some time, but I'll keep at it, don't you worry.Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com1tag:blogger.com,1999:blog-7135224450787989152.post-53095324332362161332012-04-04T05:07:00.001-07:002012-04-04T05:07:55.559-07:00Punking PnkBstrK.sysMan talk about being out of ones league! So I've been spending the last few days trying to brush up on how to reverse Windows Kernel drivers. First step was flipping through pages of <a href="http://www.amazon.com/Rootkits-Subverting-Windows-Greg-Hoglund/dp/0321294319" target="_blank">Rootkits: Subverting the Windows Kernel</a> to learn the basics of how kernel drivers work. I really have never looked this deep before. There is one problem with using that book as a reference, rootkit.com being you know, trashed by Lulzsec. So the links to example code and utilities no longer exist.<br />
<br />
I thought it wouldn't be all that important and I could simply connect my kernel debugger, start a game and watch the driver being loaded (by setting "bp PnkBstrK!DriverEntry" in WinDbg). Boy was I wrong, I don't know if they're doing something special to hide themselves but I couldn't for the life of me break on the driver being loaded. At first I thought I was doing something wrong, so I set the debugger to break on any module load. This can be done by breaking in the current session and going to Debug -> Event Filters and enabling the on module load option.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikvXw46-RIaMArjqRO44JTYgxR4Elo5HaKQOECKLIt-cFar63iGZsrW-laMQePLd_rx5HHyhviU3g4V63zEiDEF95NuKRlMtr9oTpzCoI1q7urEZuyfbrRKwhIiJyMjcRngeIAvEIq2fM/s1600/break.event.load.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="282" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikvXw46-RIaMArjqRO44JTYgxR4Elo5HaKQOECKLIt-cFar63iGZsrW-laMQePLd_rx5HHyhviU3g4V63zEiDEF95NuKRlMtr9oTpzCoI1q7urEZuyfbrRKwhIiJyMjcRngeIAvEIq2fM/s320/break.event.load.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">How to break on module loads (provided they aren't f'ing with you)</td></tr>
</tbody></table>
So I did this, then hit '.reboot' and watched every driver load. You can get the driver name by using the '.lastevent' command on break.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTK2fPi-QfILXhVo5vfpH1JS91uf8AYrWg4gUvgNl5jqLVVSW877z57DD985Zxg4SEba088Q9jkYobQQZS1NDAcQ8_1JqW81PtNpjP5aRVzju78Pq2WeZZS3JB4Ys_VWSfivuwSr-zpxU/s1600/break.lastevent.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTK2fPi-QfILXhVo5vfpH1JS91uf8AYrWg4gUvgNl5jqLVVSW877z57DD985Zxg4SEba088Q9jkYobQQZS1NDAcQ8_1JqW81PtNpjP5aRVzju78Pq2WeZZS3JB4Ys_VWSfivuwSr-zpxU/s400/break.lastevent.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Using .lastevent on driver load</td></tr>
</tbody></table>
So, I watched, every, stupid, friggen, driver load (there's a lot by the way). But I never saw PnkBstrK.sys load. What was really strange was I started up a game, then quit out then used Ctrl+Break to cause WinDbg to send a break. I then ran "lm" to see what modules were loaded. I started to see PnkBstrK under the Unloaded section. But.. I could never actually *catch* it loading.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFa2-pyvTmwj6arxOedqvzXBtmTXCE7Madv2JmHervcZf5w7mfUuqeUQhpOmbU45a1qBtiNtcvx0hkwpWChTKlgBd_5-i44K2LXrIJdyXRP-GT-iqci_7Z9bL1wYY8w-tTQRjgesF7X4w/s1600/game.loading.drivers.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFa2-pyvTmwj6arxOedqvzXBtmTXCE7Madv2JmHervcZf5w7mfUuqeUQhpOmbU45a1qBtiNtcvx0hkwpWChTKlgBd_5-i44K2LXrIJdyXRP-GT-iqci_7Z9bL1wYY8w-tTQRjgesF7X4w/s400/game.loading.drivers.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Game loading the drivers, and showing pnkbstrk being 'unloaded'</td></tr>
</tbody></table>
<br />
So how the hell do I break into it? Well first off, I wanted to make sure it was actually being loaded and have 100% control over loading and unloading the driver. To do this the Rootkit book suggests using InstDrv.exe, which as far as I can tell doesn't really exist any more. So instead I found a new tool to help in loading and unloading. I found a tool called <a href="http://www.jungo.com/st/windriver_usb_pci_driver_development_software.html" target="_blank">WinDriver from Jungo</a> which has a helper tool called wdreg.exe which you can use to load/unload drivers.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1U4k1OhAhwwNYsT-qIbDNkvMr439ayOnqkFWkwU7ab_xu6BJOvqIHY0HHLar6aPGPZklGyfIRcwBGmVrWi3oyPNFBQp_cJN9PqOGKW0FOQkGVI3CcVZ3VjGuSzqfLwo8y5bX7lQycr2k/s1600/wdreg.load.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1U4k1OhAhwwNYsT-qIbDNkvMr439ayOnqkFWkwU7ab_xu6BJOvqIHY0HHLar6aPGPZklGyfIRcwBGmVrWi3oyPNFBQp_cJN9PqOGKW0FOQkGVI3CcVZ3VjGuSzqfLwo8y5bX7lQycr2k/s400/wdreg.load.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Using wdreg to load PnkBstrK</td></tr>
</tbody></table>
By running the command "wdreg.exe -file PnkBstrK install" you can have the PnkBstrK.sys driver loaded and installed. Notice you don't pass the .sys and you are also required to use the full path (I copied it to the WinDriver directory). So I kept loading/unloading and *still* wasn't able to break. So I started searching around for other methods. Some <a href="http://www.osronline.com/showThread.cfm?link=94602" target="_blank">forums suggested using WinDbg's "bu" command</a>. This did not work. Next I visited openrce to see if they had any tips and <a href="http://www.openrce.org/forums/posts/600" target="_blank">found this</a>. Which inevitably lead me to searching for and setting a breakpoint on IopLoadDriver. As an added bonus I found a <a href="https://twitter.com/#!/Ivanlef0u/status/15097666217" target="_blank">tweet by stupid smart @Ivanlef0u</a> which was the command I needed: <br />
<span style="color: white; font-family: Georgia, 'Times New Roman', serif; font-size: 22px; line-height: 28px;">bp nt!IopLoadDriver+0x66a</span> . Yeah that pasted big, but you know what? I don't care, it deserves that font size, because it friggen worked.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQvW5ZLCv5tM8b3AAUIte3cpn8vlVlrW-7YTRhASLeAzyBwbZfXiZuXtMPlsJaR1g9s-qDaTB2yfLXFp4ASnczZQoZLXow3ZL33VN2SmmbY4LmOZmc2WW-fmkAvWhdOAN1RS5_1qZhoDo/s1600/bp.in.pnkbstrk.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQvW5ZLCv5tM8b3AAUIte3cpn8vlVlrW-7YTRhASLeAzyBwbZfXiZuXtMPlsJaR1g9s-qDaTB2yfLXFp4ASnczZQoZLXow3ZL33VN2SmmbY4LmOZmc2WW-fmkAvWhdOAN1RS5_1qZhoDo/s400/bp.in.pnkbstrk.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">call'ing into PnkBstrK.sys FINALLY!</td></tr>
</tbody></table>
<div>
Now I can start to figure out their dinky little xor obfuscation and see what ioctrl's it uses with the various services... Yay!</div>
<div>
<br />
<br />
<br /></div>Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com0tag:blogger.com,1999:blog-7135224450787989152.post-92180600142699769232012-03-23T20:44:00.001-07:002012-03-23T20:47:35.478-07:00Asmjit Based LoaderThe reason I'm using asmjit is because it's much better than writing inline assembly. When I used to write memory corruption exploits and shellcode, I used to have to write __asm {} blocks, compile it, look at the generated asm in a debugger/hex editor, copy the bytes, create a char buffer with the data in hex and finally do stupidly crazy unreadable indirection to call it. Like ((void (*)(void)) &shellcode)(); I still don't understand that shit. Overall, it was a very delicate and irritating process.<br />
<br />
With asmjit I don't have to do any of that crap. Asmjit is great because it totally abstracts out how you create your instructions, gives you type safety and allows you to serialize the code into data (which I demonstrate in this post). It also contains functions on relocating addresses for when you inject into a remote process.<br />
<br />
Asmjit exposes two objects, a compiler and an assembler. I'm not entirely sure about all of the differences, but from what I can tell the compiler seems to be an abstraction on top of the assembler. I believe it is for writing 'higher level' assembly, but in my case I want to write to registers directly because I know exactly what I want.<br />
<br />
So what do I want? In this case I want to write a loader that can take in arbitrary dll names and function names. When I used to write shellcode I wasn't afforded one very important luxury. I was exploiting a *remote* process and had *no* idea where any addresses were. To call any win32 functions you need two things. The base address of kernel32, and a method to find the addresses of symbol names. Basically you needed to hand code your own <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx" target="_blank">GetProcAddress</a>. If you're curious of an implementation, check out this oldie but goodie at <a href="http://www.harmonysecurity.com/files/kungfoo.asm">http://www.harmonysecurity.com/files/kungfoo.asm</a>. I'm pretty sure I copied/used that shellcode at somepoint in my past :). When I first started writing the loader for this post, I was actually rewriting that block of asm in asmjit! Then I thought to myself, what the hell am I doing? I already *know* the addresses of <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx" target="_blank">GetProcAddress</a>/<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx" target="_blank">LoadLibrary</a>! It's the same for all local processes.<br />
<br />
So now I'm doing local injection which gives me, well two things. First, I can easily get the base address of kernel32 using <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms683199(v=vs.85).aspx" target="_blank">GetModuleHandle</a>. And second, I can get the addresses of <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx" target="_blank">GetProcAddress </a>and
<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx" target="_blank">LoadLibrary</a> by using none other than <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx" target="_blank">GetProcAddress</a>. Then, with the awesomeness of asmjit I can insert these addresses as immediate values directly into my Assembler. I can also write my data (such as the dll path and export name) directly into this Assembler by using the data() method and specifying the buffers and their size. I use a trick which is common in shellcode to jmp down to your data then call back up to your code. By doing this, the call instruction will take the next instruction and store it on the stack for you. You can then either pop it off, or use it directly in your calls. The rest of my code basically just goes through setting up the function calls and grabbing the addresses of the buffers, pretty simple really.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj65rs2aj56EzYGjrSLa-Mw6xDODNjdoF4d6Tnplw_pkgrKiBx6FvUnNDKeAUPCZmkmCDseG-vSPcxLNCaKto7f557MEBjqS1X3vYozl0FAURftVWHtviSZfeJ0QJAflBB8JBhaqC2jBso/s1600/asmjit.injection.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj65rs2aj56EzYGjrSLa-Mw6xDODNjdoF4d6Tnplw_pkgrKiBx6FvUnNDKeAUPCZmkmCDseG-vSPcxLNCaKto7f557MEBjqS1X3vYozl0FAURftVWHtviSZfeJ0QJAflBB8JBhaqC2jBso/s400/asmjit.injection.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Injecting a DLL and calling an exported function using asmjit</td></tr>
</tbody></table>
<br />
<br />
Things of course will need to be changed once I move this code into SoNew as we will be injecting into a remote process.. But without further ado, here's my test loader code, enjoy!<br />
<br />
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeRDark.css" rel="stylesheet" type="text/css"></link>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shAutoloader.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js" type="text/javascript">
</script>
<br />
<pre class="brush: cpp">// AsmJitTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
// AsmJit - Complete JIT Assembler for C++ Language.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <asmjit/asmjit.h>
#include <asmjit/memorymanager.h>
// This is type of function we will generate
typedef int (*MyFn)();
int main(int argc, char* argv[])
{
using namespace AsmJit;
const char *dll = "C:\\Research\\SoNew\\Debug\\SoNewTestDll.dll";
const char *exported_function = "RunTest";
HMODULE kernel = GetModuleHandle(L"kernel32"); // need kernel32's base address
FARPROC load_library = GetProcAddress(kernel, "LoadLibraryA"); // need ll
FARPROC get_proc_address = GetProcAddress(kernel, "GetProcAddress"); // heh :>.
if (load_library == NULL) {
printf("load_library is null: %d",GetLastError());
return -1;
}
if (get_proc_address == NULL) {
printf("get_proc_address is null: %d",GetLastError());
return -1;
}
// ==========================================================================
// Create Assembler.
Assembler a;
FileLogger logger(stderr);
a.setLogger(&logger);
{
Label L_lib = a.newLabel();
Label L_start = a.newLabel();
Label L_funcname = a.newLabel();
Label L_callfunc = a.newLabel();
Label L_exit = a.newLabel();
// Prolog.
a.push(ebp);
a.mov(ebp, esp);
a.jmp(L_lib); // jmp down to where our lib/dll is.
a.bind(L_start); // oh hai again!
// Start.
// just to show eax contains addr (next two calls not needed)
//a.pop(eax); // address of our dll.
//a.push(eax); // push on to stack for ll call
a.call((sysint_t)load_library); // load our dll
a.cmp(eax, 0); // module should be stored in eax.
a.je(L_exit); // make sure we have a valid module handle
a.mov(edx, eax); // store module in edx
a.jmp(L_funcname); // get the exported_func's address
a.bind(L_callfunc);
// just to show eax contains addr (next two calls not needed)
//a.pop(eax); // the name of our exported func
//a.push(eax); // push name of our exported func
a.push(edx); // push addr of our dll
a.call((sysint_t)get_proc_address); // get exported_func's addr.
a.cmp(eax, 0); // func should be stored in eax.
a.je(L_exit); // if not bomb out
a.call(eax); // and call it!
// Epilog.
a.bind(L_exit);
a.mov(esp, ebp);
a.pop(ebp);
a.ret();
// our "data" section
a.bind(L_lib);
a.call(L_start);
// write our dll path as data.
a.data(dll, strlen(dll)+1);
a.bind(L_funcname);
a.call(L_callfunc);
// write our exported function name as data
a.data(exported_function, strlen(exported_function)+1);
}
// This is entirely to demonstrate how we can treat the
// code as data. If we are going to inject into a remote
// process we will need to relocate it differently.
// But for local processes it gets the point across!
size_t code_size = a.getCodeSize();
MemoryManager *mm = MemoryManager::getGlobal();
void *p = mm->alloc(code_size, MEMORY_ALLOC_FREEABLE);
if (p == NULL) {
printf("Error allocation of our code buffer returned null!");
return -1;
}
void *data = a.make();
memcpy(p, data, code_size);
a.relocCode(p);
printf("Code size: %d\nNow Calling...", code_size);
((void (*)(void)) p)();
MemoryManager::getGlobal()->free(p);
// Or screw all that above noise and just cast and call.
// MyFn fn = function_cast<myfn>(a.make());
// fn();
// MemoryManager::getGlobal()->free((void*)fn);
return 0;
}
</pre>
<script type="text/javascript">
SyntaxHighlighter.all()
</script>Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com3tag:blogger.com,1999:blog-7135224450787989152.post-42644169448975766642012-03-22T07:23:00.003-07:002012-03-22T07:23:37.067-07:00Asmjit InstallationWhile some what known in the game hacking community. I don't think a lot of people know about <a href="http://code.google.com/p/asmjit/" target="_blank">asmjit</a>. While it's taken me a bit to wrap my head around how it works (boy did that take a while) I must say it's pretty damn cool. So what it is <a href="http://code.google.com/p/asmjit/" target="_blank">asmjit</a>? Well it let's you basically dynamically create assembly opcodes via C++. Why would you want to do that? Because in-lining asm is a pain when you want to play with the raw bytes. This way we can dynamically create our <a href="http://en.wikipedia.org/wiki/Position-independent_code" target="_blank">PIC</a> and hopefully be able to stuff it into a remote process. Infact, the authors of
<a href="http://code.google.com/p/asmjit/" target="_blank">asmjit</a> apparently already saw this as a good use and already created a <a href="http://code.google.com/p/asmjit/source/browse/trunk/AsmJit-Ext/AsmJit-Ext/RemoteCodeGenerator/RemoteCodeGenerator.cpp" target="_blank">remote injector</a> for us!<br />
<br />
So <a href="http://code.google.com/p/asmjit/" target="_blank">asmjit</a> isn't a very straight forward setup. Here's the steps I had to do to get it all working.<br />
1. Download <a href="http://code.google.com/p/asmjit/" target="_blank">asmjit</a> from svn:<br />
<b> svn checkout http://asmjit.googlecode.com/svn/trunk/ asmjit</b><br />
2. Download cmake from: <a href="http://www.cmake.org/cmake/resources/software.html">http://www.cmake.org/cmake/resources/software.html</a><br />
3. Go to <where you downloaded>\AsmJit\AsmJit-1.0\Util. and run configure-windows-vs2008-x86.bat or which ever arch/Visual Studio version you want. If it doesn't work make sure cmake is in your path (or just modify the bat file to call the full path of cmake.exe<br />
4. Now go to your AsmJit-1.0\Build folder and you should see all the project files. Open up AsmJit.sln or just AsmJit.vcproj and build it.<br />
5. The last step should have produced a Debug directory and the AsmJit.dll and AsmJit.lib files.<br />
<br />
Now to use AsmJit in your project do the following:<br />
1. Create a new visual studio project -> win32 -> console -> Console Application and make sure "Precompiled header" is selected, and finish.<br />
2. Right click on the project properties and add the "Include Directories", in my case it was in E:\Research\...<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJFVmHAX9Z-5j5uFgz3LfguvkkpX1TWAlo2CHOI4RjMaBwX2ZnaIAaecg-UdNswO1VbFNEISbCFBUPxaX-aO87zUcgESQal5xodn_rhNzrJjWMvrUzv21rj3vBpmRf9IPD0DCjwO-M94U/s1600/asmjit.cpp.general.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJFVmHAX9Z-5j5uFgz3LfguvkkpX1TWAlo2CHOI4RjMaBwX2ZnaIAaecg-UdNswO1VbFNEISbCFBUPxaX-aO87zUcgESQal5xodn_rhNzrJjWMvrUzv21rj3vBpmRf9IPD0DCjwO-M94U/s320/asmjit.cpp.general.png" width="320" /></a></div>
<br />
3. Now go down to Linker and add the AsmJit.lib<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8utF8xmGDXx7cpg9t1FwcBxbUElMiepk-WW_H6cjujUy0N9MjMLebO2P0uOsX0CJ43kgkAl_Vl-rdBvtydf5mwDKG1Tr0gW7aU1NW27znPQL6ukre2OLG-Z3I2zjT3ly4Re-SDrERqw0/s1600/asmjit.cpp.linker.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8utF8xmGDXx7cpg9t1FwcBxbUElMiepk-WW_H6cjujUy0N9MjMLebO2P0uOsX0CJ43kgkAl_Vl-rdBvtydf5mwDKG1Tr0gW7aU1NW27znPQL6ukre2OLG-Z3I2zjT3ly4Re-SDrERqw0/s320/asmjit.cpp.linker.png" width="320" /></a></div>
4. Of course Visual Studio needs to know where to find AsmJit.lib, so in VS 2008 you will need to add it to your library path.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgztW7_Ocf_Yy_59yzOXIcQkNo1xKP5qG78K6dn19QMUry3VzAHyFlOvolXO2Tjw1IbJ8WfmnXAzS1LU3ZwuwGDUV2THCOck1JBG4_tA-FdvZE2bFaA6FsMcYa3oijTa739OlJthTdanwA/s1600/asmjit.options.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgztW7_Ocf_Yy_59yzOXIcQkNo1xKP5qG78K6dn19QMUry3VzAHyFlOvolXO2Tjw1IbJ8WfmnXAzS1LU3ZwuwGDUV2THCOck1JBG4_tA-FdvZE2bFaA6FsMcYa3oijTa739OlJthTdanwA/s320/asmjit.options.png" width="320" /></a></div>
5. Now you should be able to build and play with asmjit. (You'll probably need to copy the AsmJit.dll file to your executable's directory before running.)<br />
<br />
<br />
I've got some working code already for calling MessageBox via assembly but I'll post that tomorrow. Enjoy for now!<br />
<br />Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com1tag:blogger.com,1999:blog-7135224450787989152.post-57965132978255143232012-03-20T05:05:00.005-07:002012-03-20T05:05:46.925-07:00A Quick Look at Punk Busters Installation.I don't want to get my gaming machine's hardware or my personal account banned, so I've setup a target game in virtualization software to insulate myself:<br />
Free Windows XP images: <a href="http://www.microsoft.com/download/en/details.aspx?id=11575" target="_blank">Microsoft IE App Compat</a>.<br />
Free Virtualization software with 3d support: <a href="http://www.vmware.com/products/player/overview.html" target="_blank">VMWare Player</a> (I'm using Workstation however). You'll need to enable 3d acceleration for any DirectX game to start.<br />
Free Kernel debugger: <a href="http://msdn.microsoft.com/en-us/windows/hardware/gg463009" target="_blank">Microsoft's WinDBG</a>.<br />
Free Target game to hack: <a href="http://battlefield.play4free.com/en/" target="_blank">EA's Battlefield play4free</a>.<br />
<br />
I had to convert the IE Compat Virtual PC images to VMWare using VMWare's free <a href="http://downloads.vmware.com/d/info/infrastructure_operations_management/vmware_vcenter_converter_standalone/5_0" target="_blank">image converter tool</a>. The next step was getting the kernel debugger hooked up from my host system to the XP image.<br />
This requires 4 easy steps:<br />
1. Create a named pipe in VMware. From the VM settings -> Add -> Serial Port -> Named Pipe -> \\.\pipe\com_1 or whatever you want to call it.<br />
2. Modify the boot.ini in XP to map a COM port for debugging. The config should look like this.<br />
<br />
[boot loader]<br />
timeout=30<br />
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS<br />
[operating systems]<br />
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect<br />
<b>multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional - Debug" /fastdetect /debug /debugport=com1 /baudrate=115200</b><br />
<br />
3. Reboot XP, select Microsoft Windows XP Professional - Debug<br />
4. Start windbg with the following command line or make a shortcut like I did: "C:\Program Files (x86)\Debugging Tools for Windows (x86)\windbg.exe" -b -k com:pipe,port=\\.\pipe\com_1,resets=0<br />
<br />
If everything went right you should see something like this:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYyDtdqdnx_UrhzHwknVyFOE5kNmF3dMJqilhcvSFArdIsU4w4F_azR-FqlcYg19ioHXtKzx3dFeKkC_M_Yp7_ro7Woram8eSmgO2YnZrY4_R5PesFqvRXQhujThK3Md5IXrLat6ifJWk/s1600/kerneldebug.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYyDtdqdnx_UrhzHwknVyFOE5kNmF3dMJqilhcvSFArdIsU4w4F_azR-FqlcYg19ioHXtKzx3dFeKkC_M_Yp7_ro7Woram8eSmgO2YnZrY4_R5PesFqvRXQhujThK3Md5IXrLat6ifJWk/s400/kerneldebug.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">WinDBG connected to our VMWare image and the PnkBstrK.sys module loaded (or rather, unloaded)</td></tr>
</tbody></table>
If everything *isn't* working you'll probably want to read <a href="http://silverstr.ufies.org/lotr0/windbg-vmware.html" target="_blank">this link</a> on how to setup vmware for windbg debugging.<br />
<br />
While I was installing the Battlefield Play4Free game I loaded up<a href="http://technet.microsoft.com/en-us/sysinternals/bb896642" target="_blank"> filemon.exe from Sysinternals</a> to see what files got placed on the system. During the "Installing PunkBuster" splash screen I noticed the following files were installed:<br />
- <b>C:\windows\system32\drivers\PnkBstrK.sys -</b> The kernel driver, appears to be partially obfuscated using XOR.<br />
- <b>C:\windows\system32\PnkBstrA.exe -</b> The Punk Buster service A. (I think this just downloads B, will RE to confirm).<br />
- <b>C:\windows\system32\PnkBstrB.exe -</b> The Punk Buster service B.<br />
- <b>C:\windows\system32\PnkBstrB.xtr -</b> The original downloaded form of PnkBstrB.exe (I think this is a guess because file size is the same)<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pbsvc_p4f.exe -</b> The punk buster installer / remover service checking tool<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pb\pbcl.db -</b> Looks to be a list of servers, ports and hashes of some sort (for installed files maybe?).<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pb\pbcl.log -</b> Client log, shows connection/update query information.<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pb\pbag.dll -</b> Single export name of 'a' looks to be doing some sort of obfuscation. Not sure on purpose yet.<br />
<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pb\pbcl.dll -</b> Not too sure, exports two names 'ca' and 'cb' both of which look to be doing weird jmp calls. By looks of the strings appears to communicate with the punk buster servers. Guessing by the name alone, probably the punk buster client.<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pb\pbclgame.cfg -</b> Contains the line: "cl_punkbuster 1"<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pb\pbns.dat -</b> Unknown data format<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pb\pbns_c.dat -</b> Same as above, with 16 bytes differing.<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pb\pbsvc_p4f.exe -</b> The punk buster installer / remover service checking tool<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pb\dll\wa001377.dll -</b> Appears to be related to the html file full of signatures/hashes.<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pb\dll\wc002244.dll - </b>Appears to be related to the html file full of signatures/hashes.<br />
<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pb\htm\wa001377.htm -</b> Appears to be signatures/hashes. Probably for known hacks<br />
- <b>C:\Program Files\EA Games\Battlefield Play4Free\pb\htm\wc002244.htm -</b> Same as above.<br />
<br class="Apple-interchange-newline" /><br />
So that's my target, of course everything I stated above is speculation as to the files purpose. I will be debugging it to learn more details the coming weeks.<br />
<br />
Ahh it's good to have a target :><br />
<br />
<br class="Apple-interchange-newline" /><br />
<br />
<br />Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com0tag:blogger.com,1999:blog-7135224450787989152.post-51442906948342862862012-03-18T01:03:00.001-07:002012-03-18T01:05:58.756-07:00Anti-Cheat SystemsThere's no point in cheating if you don't at least try to not get caught. However, let me make one thing perfectly clear. I hate cheaters, I think they are terrible little shit heads and they ruin games. Like, I really hate them, that is part of the reason *why* I'm doing this. I want to learn how it all works so I can actually determine if I think someone is cheating or not. Simply saying 'hax!' or 'shut off your aimbot!' is stupid, 90% of the time it's most likely because the other player is just better than you. But for those 10%... wouldn't it be nice to determine what is really possible? Well I certainly do.<br />
<br />
There is one very big problem. I'm starting this project *really* late. I have about 10 years or so worth of catching up to do. I'm sure if any real game hackers are reading my posts they're laughing at me because they know my silly little injection methods will probably get busted immediately. Reading through some anti-cheat forums is depressing for multiple reasons; lack of English ability being a primary one (and I don't mean non-native people, holy hell) and another being for how behind I really am. But that is not going to stop me, I realized when I started this was going to be a long ass project.<br />
<br />
From my limited research there are basically three major anti-cheating systems: <a href="http://global.nprotect.com/GGP_download/index.php?user_lang=en" target="_blank">nProtect GameGuard</a>, <a href="http://en.wikipedia.org/wiki/Valve_Anti-Cheat" target="_blank">Valve Anti-Cheat</a> (VAC/VAC2) and <a href="http://www.evenbalance.com/" target="_blank">PunkBuster</a>. nProtect appears to be mainly focused on asian MMORPGs like Lineage II and Aion etc. I really don't like asian MMO's, so probably not worth my time. Valve's system is used in a Lot of games, a lot of which I do play like Shogun Total War 2 etc, but not so interesting for me. Finally, we have PunkBuster. This is used by a lot of EA's games. I hate EA. I mean, *really* hate EA. Part of the reason I even took up this project was because they screwed me over on a number of occasions to the point I couldn't play their games. Living in a country outside of the States has it's downsides. If you're keeping tally, I hate cheaters and I hate EA. I think I hate EA more.<br />
<br />
So, I think I'll focus on PunkBuster, at least to begin. Free 2 play games are the new thing, and EA has a number of them. Battlefield Heroes, Battlefield free 2 play and so on, and I think these would be an excellent start because, they're free and I don't care if I get banned. One thing I have been reading about is newer versions of PunkBuster do hardware based banning. They have a device driver running in ring 0 and supposedly grab hardware ID's to use as global bans. That's not cool, but I guess I can see the point of it when you introduce free to play games. No point banning if someone can just make a new free account.<br />
<br />
I need to create a VM (because I'm sure as shit not going to get my gaming box banned) and download the punkbuster service and start reversing. If you're bored you can read PunkBuster's '<a href="http://www.evenbalance.com/index.php?page=pbsvcfaq.php" target="_blank">FAQ</a>' to get a general idea of what it does. After reading some cheater forums on these systems I realized most people don't know what the hell they are talking about. Basing anything off these people's information is stupid and dangerous. So yeah, the next few posts will probably be about reversing punk buster and hopefully learning some interesting anti-cheat methods!<br />
<br />
<br />
<br />
<br />
<br />
<br />Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com0tag:blogger.com,1999:blog-7135224450787989152.post-29056543720730316542012-03-17T02:34:00.003-07:002012-03-17T02:36:11.133-07:00Process Injection with SoNewSo I finally finished at least the first method of DLL injection using my new injection framework. I'm not entirely convinced my class layout is the best, but it looks at first glance like this abstraction should be OK for handling the various injection methods. I've also had thoughts of scraping DLL injection entirely and focusing on building a custom game debugging engine that would allow me to use the power of windbg and python via the python interpreter extension to script up games. Regardless, I'm going to keep plugging away at SoNew because I'm learning a lot about windows junk that I should have known but never invested any of my time in researching.<br />
<br />
As a side note, I have a terrible habit of buying very expensive technical books and only reading the first chapter. This game hacking project of mine has shown me I own a lot of books with good information that I can use. For example I didn't realize the <a href="http://www.amazon.com/Windows-via-Pro-Jeffrey-Richter/dp/0735624240" target="_blank">Windows Via C/C++ </a>book I bought years ago had an entire chapter on DLL injection. There's also some great information regarding Windows Internals in it as well.<br />
<br />
So here's the basic run down of how SoNew works. There are three objects; a process, an injector, and the injector details. The Process object obviously represents the process we are injecting into. In the future I plan on exposing more methods of mucking with the internals of a remote process (exposing read/write process memory etc.). The Injector is an abstraction of the various injection methods. This is created with various attributes that the user specifies via command line arguments. Once we have our injector object created, we pass it to the process' InjectInto method which will handle the injection/execution of our DLL or code. This *should* make it easy for us to create new injection method classes and not have to change anything about how we inject, it's entirely up to the injection class to handle the details.<br />
<br />
As for the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx" target="_blank">CreateRemoteThread </a>& <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx" target="_blank">LoadLibrary </a>method of injection. I'm not going to go into gory details on how it works because there's really a ton of information out there already. However, here's the quick run down:<br />
1. Use <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx" target="_blank">OpenProcess </a>to get a handle to the remote process, making sure to pass flags that give us proper permissions.<br />
2. Call <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366890(v=vs.85).aspx" target="_blank">VirtualAllocEx </a>passing in the handle to the process and how much space we want to allocate. In this case, we only allocate strlen(<dll path string size>). It returns the address in the remote process where this string is stored.<br />
3. Call <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms681674(v=vs.85).aspx" target="_blank">WriteProcessMemory </a>passing in the process handle, the address we got from <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366890(v=vs.85).aspx" target="_blank">VirtualAllocEx</a>, the dll path string, and the length of said string.<br />
4. At this point we have injected all the necessary details. We then switch to our Execute() method of our injector.<br />
*5. We need to get the address of <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx" target="_blank">LoadLibraryA</a>(or W). So we use <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx" target="_blank">GetProcAddress </a>passing in kernel32's handle (via GetModuleHandle) and the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx" target="_blank">LoadLibraryA</a> string. We cast the FARPROC return value of <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx" target="_blank">GetProcAddress </a>as being a PTHREAD_START_ROUTINE because it has the same basic call structure as ThreadFunc.<br />
6. Finally we call <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx" target="_blank">CreateRemoteThread</a>, passing in the process handle (from step 1), the address of
<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx" target="_blank">LoadLibraryA</a> (from step 5), and the address of our DLL string in the remote processes memory (from step 2/3).<br />
<br />
That's pretty much all there is to it. Note on step 5, I had some initial concerns that due to recent advancement of <a href="http://blogs.msdn.com/b/michael_howard/archive/2006/05/26/address-space-layout-randomization-in-windows-vista.aspx" target="_blank">ASLR </a>that getting the address of <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx" target="_blank">LoadLibraryA </a>from SoNew's process wouldn't be the same address of the process that I'm injecting into. But thankfully the address is the same on all processes (however it does change on reboot, but again all processes share the same address, so whatever.) So, we can do this... but uh it's kind of useless. We have no way of doing communication between SoNew and the injected code. Also I only got the DllMain to fire, not an exported function. This is extremely limiting. I think I'll figure out how to call exported functions from the DLL next. Also, I've read of people using things like named pipes to synchronize information between injector and injectee which might be worth implementing.<br />
<br />
However, the more I think about all of this, the more I'd rather have a sweet debugger/injector that gives me access to a python interpreter. Maybe I'll make another side project for that :>.<br />
<br />
I have also started to realize I need to start looking into what anti-debugging tricks game protection systems are using. No point in writing all this if something like PunkBuster hooks <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx" target="_blank">CreateRemoteThread</a> and kills your hacks immediately (then bans the hell out of you). If anyone who does this stuff knows what methods games are using these days, please contact me :>.<br />
<br />
As for how to actually use SoNew here's an example of me injecting the SoNewTestDll.dll into winamp.exe.<br />
Note all it does is pop up a MessageBox.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbuhKPth4nl0YA_aJK9eWO9LUHWz-pan-o4juhhh6nIQwEbyt9UbAixCLEUSpKyXUMoRbV_h3cTRzKqayWF0Igv4xOsNFPX5S32rvyi23kM_gcq-oZVtBcdWSncGmy2mWpWA4zsFQ2x94/s1600/SoNew.Injection.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbuhKPth4nl0YA_aJK9eWO9LUHWz-pan-o4juhhh6nIQwEbyt9UbAixCLEUSpKyXUMoRbV_h3cTRzKqayWF0Igv4xOsNFPX5S32rvyi23kM_gcq-oZVtBcdWSncGmy2mWpWA4zsFQ2x94/s400/SoNew.Injection.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">SoNew Injecting into winamp.exe.</td></tr>
</tbody></table>
<br />
Oh and you can download SoNew from <a href="https://github.com/wirepair/SoNew/">https://github.com/wirepair/SoNew/</a>. Enjoy the bugginess!<br />
<br />Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com2tag:blogger.com,1999:blog-7135224450787989152.post-65743292133619348362012-03-01T02:14:00.002-08:002012-03-01T02:14:47.774-08:00BuhOK Work has been taking up all my time (including weekends) so I haven't been able to put much time into this. Right now I'm going through QT's source tree to learn somethings and copy their command line handling code :>. It'll be a while before I release anything cool :/.<br />
<br />Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com1tag:blogger.com,1999:blog-7135224450787989152.post-5440240839317229232012-02-19T02:35:00.000-08:002012-02-19T02:35:23.566-08:00SoNew BeginsSo I've finally got around to actually starting a project for my injector. I've aptly named it SoNew (挿入 means insertion in Japanese). I've broken my solution into three projects. A command line tool, GUI tool and a sample DLL for injection. I plan on supporting injecting a DLL and having it automatically executed through Dllmain, as well as giving an option for executing via an exported function name. I should have at least a basic working example done by next week (or earlier depending on my work...) in which I'll start <a href="https://github.com/wirepair/SoNew" target="_blank">pushing to github</a>. I don't promise the code to be pretty but it should look like:<br />
<br />
<pre style="background: #000000; color: #d1d1d1;">Process proc <span style="color: #d2cd86;">=</span> Process<span style="color: #d2cd86;">(</span><span style="color: #d2cd86;"><</span>pid<span style="color: #d2cd86;">></span><span style="color: #d2cd86;">)</span><span style="color: #b060b0;">;</span> <span style="color: #9999a9;">// Or Process(<processname.exe>);</span>
proc<span style="color: #d2cd86;">.</span>Method<span style="color: #d2cd86;">(</span>methods<span style="color: #d2cd86;">.</span>CRTAndLoadLib<span style="color: #d2cd86;">)</span><span style="color: #b060b0;">;</span> <span style="color: #9999a9;">// Or methods.CRTAndWriteMem, methods.IATHooks</span>
proc<span style="color: #d2cd86;">.</span>injectDll<span style="color: #d2cd86;">(</span><span style="color: #d2cd86;"><</span>path to dll<span style="color: #d2cd86;">></span><span style="color: #d2cd86;">)</span><span style="color: #b060b0;">;</span> <span style="color: #9999a9;">// either executes here or..</span>
proc<span style="color: #d2cd86;">.</span>executeFunc<span style="color: #d2cd86;">(</span><span style="color: #d2cd86;"><</span>funcname<span style="color: #d2cd86;">></span><span style="color: #d2cd86;">)</span><span style="color: #b060b0;">;</span> <span style="color: #9999a9;">// executes the dll's function @ funcname.</span>
</pre>
<br />
I'll throw in a .NET forms GUI to wrap all the command line nastiness after I get some injection methods built in. That's it for now!Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com0tag:blogger.com,1999:blog-7135224450787989152.post-38407484867683381602012-02-01T02:26:00.000-08:002012-02-01T02:26:21.658-08:00Goals for FebruaryJust wanted to give a quick update, that <b><i>yes</i></b> I am still working on this. I realized my C++ is total crap so I've gone back and started reading my <a href="http://www.amazon.com/Ivor-Hortons-Beginning-ANSI-Complete/dp/1590592271/ref=sr_1_1?ie=UTF8&qid=1328091487&sr=8-1" target="_blank">ANSI C++ Book</a>. I've been reading and doing the examples of about a chapter every two days, or roughly 30 pages a day. Out of all the programming books I've ever bought, I don't think I've actually read them front to back like I have this one. It's weird when you're actually motivated to do something on your own like this. I've always enjoyed coding (mainly python) but I never thought I'd actually read a whole book on it. I also took the time to find a <a href="http://www.amazon.com/Introduction-Game-Programming-Direct-9-0c/dp/1598220160/ref=sr_1_1?ie=UTF8&qid=1328091595&sr=8-1" target="_blank">DirectX9 book by Frank D. Luna</a> which I'll study at the same time. Anyways, I'm getting off track here.<br />
<br />
My goals for February are this (warning they're pretty boring):<br />
1. Finish reading my C++ book<br />
2. Start reading the DirectX9 book and get through at least the first 10 chapters.<br />
3. Craft an initial version of my hooking library. It will be as generic as possible to allow for extending it easily.<br />
4. Implement at least four methods of hooking/injection.<br />
5. Try to come up with decent reasons to make sure this blog doesn't go stale, but not post useless posts like this one. (I friggen hate when blogs go stale).<br />
<br />
Anyways, stay tuned I'm about halfway done with the C++ book and it's starting to come back to me, so I should have *some* code available soon.<br />
<br />Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com1tag:blogger.com,1999:blog-7135224450787989152.post-45821139016990591532012-01-25T05:37:00.000-08:002012-01-25T06:43:46.225-08:0010 User-Mode Methods of Code Execution/Injection<br />
So before I even start writing any terrible code (which it totally will be, as I haven't written C++ in years) I need to investigate all the ways that one can actually inject code into another process. That, obviously, is the point of this post, to highlight the ten ways that appear to be popular for injecting code into a process and a brief explanation of the method. My goal is to develop at least simple examples of each routine (Maybe not to start, but eventually). I'm going to at least attempt to build a library of the methods so it will be easy to select a method. Anyways, here's the list I came up with, if anyone has any other methods *please* email me or let me know (@_wirepair on twitter) and I'll happily add it to the list and give credit!<br />
<br />
<b>AppInit_DLLs Injection </b><br />
<b>Description</b>: Using this technique allows you to inject a single, or multiple DLLs into all user-mode processes. This is ridiculously powerful as it allows you to basically inject your code into everything that the user runs. It works by you specifying a list of DLL's separated by a comma or space you wish to load in the following registry key:<br />
<br />
<span style="font-family: 'Segoe UI', Verdana, Arial; font-size: 12px; text-align: left;">HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs</span><br />
<br />
There's a great excerpt from the Microsoft documentation (referenced below) regarding AppInit_DLLs:<br />
<blockquote class="tr_bq">
"<span lang="EN-US" style="font-family: Calibri, sans-serif; font-size: 11pt;">Today, only a small set of
legitimate applications use this mechanism. Unfortunately, a larger set of
malware use this mechanism. Applications and malicious software both use
AppInit DLLs for the same basic reason, which is to hook APIs"</span></blockquote>
Due to the abuse, Microsoft built in some code-signing requirements but I don't understand the point as they can just be disabled by setting the RequireSignedAppInit_DLLs key to 0x0. <br />
<b style="font-family: inherit;">Required Work</b><span style="font-family: inherit;"><b>:</b> Build a safe DLL that can be loaded into any process without crashing it, hook various API calls.</span><br />
<b>References:</b> <a href="http://www.blogger.com/"><span id="goog_749298787"></span>A 30 page Word Document explaining AppInit_DLLs<span id="goog_749298788"></span></a>.<br />
<b>References:</b> <a href="http://msdn.microsoft.com/en-us/library/dd744762(v=vs.85).aspx" target="_blank">Simple explanation with registry key information</a>.<br />
<br />
<b>SetWindowsHookEx</b><br />
<b>Description: </b>I'd basically describe this as the 'polite way' to inject your code into a process and hook a function or API call. While this can be used to install a global hook for all processes, you can also use it for hooking a single thread. Much like AppInit_DLLs this also injects a DLL into a remote process. To remove the hook you simply call UnhookWindowsHookEx (keep in mind this won't remove the DLL from the process).<br />
<b>Required Work:</b> Probably the same amount as AppInit_DLLs.<br />
<b>References: </b><a href="http://www.codeproject.com/Articles/4610/Three-Ways-to-Inject-Your-Code-into-Another-Proces#section_1" target="_blank">A nice write up from CodeProject</a>.<br />
<b>References:</b> <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms644960(v=vs.85).aspx" target="_blank">Using Hooks (MSDN)</a><br />
<b>References</b>: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx" target="_blank">SetWindowsHookEx API from MSDN</a><br />
<br />
<b>CreateRemoteThread & LoadLibrary</b><br />
<b>Description:</b> This method is starting to look a bit better. Again we're loading a DLL but this time using CreateRemoteThread to force the remote process to do it. This will however require come up with our own method to hook, or modify our target functions/code as well as potentially code for handling inter process communication between the injector and the injected. Also dependent on LoadLibrary to find function names, which may or may not be modified by anti-cheating systems.<br />
<b>Required Work: </b>Quite a bit more work than SetWindowsHookEx, due to custom hooking (and possibly IPC code) required.<br />
<b>References: </b><a href="http://www.codeproject.com/Articles/4610/Three-Ways-to-Inject-Your-Code-into-Another-Proces#section_2" target="_blank">A nice write up from CodeProject</a><br />
<b>References:</b> <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx" target="_blank">CreateRemoteThread API Call</a> and <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx" target="_blank">LoadLibrary API Call</a> from MSDN.
<br />
<br />
<b>CreateRemoteThread & WriteProcessMemory</b><br />
<b>Description:</b> So far, this one is my favorite (few left to go though!). Mainly because in this method you're not even injecting a separate DLL but just the code you need. However, you still end up relying on LoadLibrary to find your functions which some anti-cheating systems may have hooked/modified.<br />
<b>Required Work: </b>Depends on code that I create, it appears to be some restrictions when using this technique (with regards to variable count/size). Also may or may not require some IPC code.<br />
<b>References:</b> <a href="http://www.codeproject.com/Articles/4610/Three-Ways-to-Inject-Your-Code-into-Another-Proces#section_3" target="_blank">A nice write up from CodeProject</a><br />
<b>References:</b> <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx" target="_blank">CreateRemoteThread API Call</a>, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx" target="_blank">LoadLibrary API Call</a> and <a href="http://msdn.microsoft.com/en-us/library/ms681674" target="_blank">WriteProcessMemory API Call</a> from MSDN.
<br />
<br />
<b>Exploit Memory Corruption Bug</b> :><br />
<b>Description: </b>My good ol' friend, Memory Corruption. The idea being that you exploit a buffer overflow/ptr overwrite or something else that allows you to gain control of the program. I'm far more familiar with using techniques like these, but it's kinda silly to go down this route for a local application.<br />
<b>Required Work: </b>Unnecessary<br />
<b>References: </b>The internet<br />
<br />
<b>Code Cave</b><br />
<b>Description:</b> OK now this one is my favorite. Very similiar to CreateRemoteThread & WriteProcessMemory, except you use a different technique for getting your code to execute after injection. The basic flow is: OpenProcess -> VirtualAlloc -> WriteProcessMemory -> Pause Thread -> Get Context -> SetThreadContext -> ResumeThread (starts your code).<br />
<b>Required Work: </b>About the same as CreateRemoteThread & WriteProcessMemory except requires inline'd x86 asm.<br />
<b>References: </b><a href="http://www.blizzhackers.cc/viewtopic.php?p=2483118" target="_blank">Nice write up on a forum post from Blizzhackers</a><br />
<br />
<b>IAT Hooks</b><br />
<b>Description: </b>This method requires overwriting target addresses in the <a href="http://en.wikipedia.org/wiki/Portable_Executable#Import_Table" target="_blank">Import Address Table (IAT)</a>. I assume this method is pretty easy to detect for anti-cheat systems. But it remains popular in malware at least. Also depending on the application, some calls may be using LoadLibrary and GetProcAddress (i.e. calling functions dynamically) which would completely bypass the IAT hook.<br />
<b>Required Work: DC,NGDI (</b>Don't Care, Not Gonna Do It.)<br />
<b>References:</b> <a href="http://www.autosectools.com/IAT-Hooking-Revisited.pdf" target="_blank">A newer approach to IAT Hooking, looks interesting...</a> along with <a href="http://code.google.com/p/iat-hooking-revisited/" target="_blank">source</a>.<br />
<b>References: </b><a href="http://msdn.microsoft.com/en-us/windows/hardware/gg463119.aspx" target="_blank">PE & COFF Specification</a><br />
<b>References:</b> <a href="http://jpassing.com/2008/01/06/using-import-address-table-hooking-for-testing/" target="_blank">Nice blog post on using IAT Hooks for mock apps.</a><br />
<b><br /></b><br />
<b>Inline Function Hooking (aka Detours)</b><br />
<b>Description: </b>The most famous version of this is the Detours library from Microsoft. Only supports 32-bit, unless you feel like dropping $10,000 for 64-bit support. It's a pretty simple approach due to the fact that functions have stub code which can be rewritten without causing problems. For a quick summary on how it works check this <a href="http://aimbots.net/tutorials/932-how-detours-work.html" target="_blank">excellent post</a> from, no less, a game hacking site!<br />
<b>Required Work: </b>Probably the same as CreateRemoteThread/WriteProcessMemory with a little bit more asm involved.<br />
<b>References: </b><a href="http://www.microsoft.com/about/legal/en/us/intellectualproperty/iplicensing/programs/detours.aspx" target="_blank">Microsoft Detours Page</a> and a old but good <a href="http://research.microsoft.com/apps/pubs/default.aspx?id=68568" target="_blank">document from MS on how Detours works</a>.<br />
<br />
<b>DLL Replacement</b><br />
<b>Description: </b>Due to the way that windows searches for libraries, it will load any .dll we put in the same path as the executable. This, obviously, can be taken advantage of to load a dll (say d3d9.dll) instead of the one in the system directory. Or we simply rename the one in the system directory. The problem here is that you'd either have to wrap every function or figure out a way to proxy function calls to the real dll. If you think this is crazy, check out what this guy did: <a href="http://graphics.stanford.edu/~mdfisher/D3D9Interceptor.html">http://graphics.stanford.edu/~mdfisher/D3D9Interceptor.html</a>. He's basically already written a lot of what I'm going to do but I need to learn, not copy & paste so I'm going to go about this my own way. (I still can't get over the awesomeness of his work, even though I've known about it for a few weeks now!)<br />
<b>Required Work: </b>Quite a bit, need to wrap pretty much every function, or figure out a way to proxy function calls to the real DLL.<br />
<b>References: </b><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx" target="_blank">Windows Library Load Order ( >= Win7)</a><br />
<b><br /></b><br />
<b>Custom Debugger</b><br />
<b>Description:</b> Finally, I can create my own debugger by wrapping dbgeng.dll and using various debugger commands and methods to gain execution and inject data/code.<br />
<b>Required Work:</b> Need to learn internals of dbgeng and wrap the necessary interfaces/methods to do what I want. So, a lot of work. Probably no time soon :>.<br />
<b>References:</b> <a href="http://devonstrawntech.tumblr.com/post/15878429193/how-to-write-a-windows-debugger-references" target="_blank">Un-friggen-real list of everything you need to 'Create your own Debugger', seriously awesome list.</a><br />
<b>References: </b><a href="http://msdn.microsoft.com/en-gb/library/ff560173.aspx" target="_blank">Using the Debugger Engine (MSDN)</a><br />
<b>References:</b> <a href="http://windbg.info/download/doc/pdf/WinDbg_A_to_Z_color.pdf" target="_blank">Awesome PDF with everything you need to know about WinDBG / dbgeng</a><br />
<br />
<br />
Some other things of note; not really an injection 'technique' but for getting managed assembly's into a process: (check out '<a href="http://www.codingthewheel.com/archives/how-to-inject-a-managed-assembly-dll" target="_blank">how to inject a managed assembly</a>', and <a href="http://blogs.msdn.com/b/jmstall/archive/2006/09/28/managed-create-remote-thread.aspx" target="_blank">CreateRemoteThread, managed style</a>.<br />
<br />
Anyways, I think i'm going to play around with some code now, so I may not have any more posts until after the weekend. Stay tuned though!<br />
<br />
<br />Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com1tag:blogger.com,1999:blog-7135224450787989152.post-73678204357944184032012-01-21T19:42:00.000-08:002012-01-21T19:42:27.816-08:00DX Debugging and Time To Make The HookersWhile earlier than I had hoped, I think it's time I make at least a basic hooking library. After some consideration I decided I want to make a generic texture hacker. Basically, I want to be able to hook the DirectX create object call and inspect the textures and then hook the SetTexture call to either modify or remove which ever textures I mark. I also would like to be able to export the texture and maybe display it on screen or at least create a hash of it. This would be good because it would enable you to specify simple hashes for textures you want to mark as red or green or whatever you want. So that's where I am at and I assume this will take me a few weeks but what I learn won't be specific to texture hacking and I'll be able to reuse a lot of it in other things. (I'm looking at tackling speed hacks next, then probably aimbots).<br />
<br />
So all this was brought about by a few things. First, I think I am doing texture hacks incorrectly. I am concerning myself too much with the application code and not the DirectX library itself. I don't know why I didn't think of this to begin with, but I don't need to find *where* in the game that it loads textures, I just need to set breakpoints on the CreateObject and SetTexture methods from dx9s.dll or whichever DirectX version is being used.<br />
<br />
When I had some free time the other day I did a quick search for DirectX debugging which lead me to information regarding Microsoft's PIX. For those who aren't aware, PIX is a free tool that comes with the DirectX SDK. It's hooks all of the DirectX calls and lets you inspect each object as it's being created. This is obviously of great interest to me as I can find all the textures being loaded. They call the profiling process 'Experiment' which is pbbfftt, but whatever. So you choose the application and select the 'A replayable Direct3D call stream, saved to file' and start the target application. Here's an 'experiment' of the Meshes DirectX sample application.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkQAP3xP9beGCYkf80jdak25Kcq9IllATM7CpU8cW2igjO4Jn1YqFQ_YB1ZzJaBt7-REvUsFzMOs0zlEwUcBQqvn8zNTLgA8oBhy68Od_pPzeyI_R59FyMC01qGO_jOTdpk76hlmZt1cs/s1600/pixrun.meshes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkQAP3xP9beGCYkf80jdak25Kcq9IllATM7CpU8cW2igjO4Jn1YqFQ_YB1ZzJaBt7-REvUsFzMOs0zlEwUcBQqvn8zNTLgA8oBhy68Od_pPzeyI_R59FyMC01qGO_jOTdpk76hlmZt1cs/s320/pixrun.meshes.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
PIXRun with the rendered tiger</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYylcCxVm60M5u9Y-uu0Ff1kTP7sLIqzGLlEzdPCPKsJdXI_vG-d1-XbLc33vD4YZ9x4297NPun_GPbUP-HoaMv8sqSa8yXyEf0H1Fkti4tvAAlsq6KSB5UU3lnWKUpQRj4YC2DxF3iRw/s1600/pixrun.meshes.texture.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYylcCxVm60M5u9Y-uu0Ff1kTP7sLIqzGLlEzdPCPKsJdXI_vG-d1-XbLc33vD4YZ9x4297NPun_GPbUP-HoaMv8sqSa8yXyEf0H1Fkti4tvAAlsq6KSB5UU3lnWKUpQRj4YC2DxF3iRw/s320/pixrun.meshes.texture.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
The captured texture</div>
<br />
In the second picture you can actually right click on the texture and save to file. Pretty neat way of extracting images/textures directly from a game. Another great thing is I can right click on the texture address and go to 'Object Creation' It will show me the exact DirectX CreateObject call that initialized that texture. It was also worth just going through an entire frame setup to see how and how many calls are actually made just to render that one single stupid friggen tiger. Quite impressive considering you should be getting about 60 frames per second.<br />
<br />
So now I want to find the SetTexture call in windbg. Here's a quick windbg session of me finding the SetTexture call in the Meshes DirectX tutorial application.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKlUThcsXoNvfb8t12U63-RWxt7B3OQhzVOKgPg9sfyxbvkernrgRWSOwUXqPuQ_U4bVvcfVeIWNYpxNqB3tZD_uSPc_kYUR5WVNrko3KMgMUFDZE45krWRn8ZnnjgN1ayspWiS-w6mn4/s1600/meshes.settexture.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKlUThcsXoNvfb8t12U63-RWxt7B3OQhzVOKgPg9sfyxbvkernrgRWSOwUXqPuQ_U4bVvcfVeIWNYpxNqB3tZD_uSPc_kYUR5WVNrko3KMgMUFDZE45krWRn8ZnnjgN1ayspWiS-w6mn4/s320/meshes.settexture.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
SetTextures call from Meshes</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I initially set the breakpoint where I knew the SetTextures call was from Meshes and followed it in to d3d9.dll. So the method I want is: d3d9!CD3DHal::SetTexture_FP. I can now just set a breakpoint on this method for the Havok demo application. Here's that debugging session:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyaQnzsclByTfGxJbpypxA7bwMOc2cGJT-A84_pby46No6QIMMOQa31AOMPd1d5lZWDsREaoCqPCTnQwXlaXCRdhVPQGEIHHC7KJeYRz_fO_wUzKSl5EaWp5CiYYO3C8SOjLSRoGd2dfE/s1600/havok.settexture.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyaQnzsclByTfGxJbpypxA7bwMOc2cGJT-A84_pby46No6QIMMOQa31AOMPd1d5lZWDsREaoCqPCTnQwXlaXCRdhVPQGEIHHC7KJeYRz_fO_wUzKSl5EaWp5CiYYO3C8SOjLSRoGd2dfE/s320/havok.settexture.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Finding and setting a breakpoint on <span style="text-align: left;">d3d9!CD3DHal::SetTexture_FP</span></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So this is all well and good, but there's a lot of set texture calls and I'd like to not have to inspect each one individually. This is why I want to build a quick hooking example that can export the textures and a hash so I can mark each one that I want set to red. If nothing else, this will allow me to brush up on my C++ which is far dustier than I hoped. So yeah, next few posts will demonstrate me flailing around with C++ and hooking. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com1tag:blogger.com,1999:blog-7135224450787989152.post-68042451562323172762012-01-19T06:03:00.000-08:002012-01-19T06:03:40.827-08:00Where I'm at with Havok (I don't know what I'm doing)So I've been playing around with the Havok 6.0 SDK (very old, but that's what ASS uses) and it comes with a series of demos that shows off the physics and animation engine. The SDK provides the engine itself as a series of static libraries (.lib files) and their associated header files. Since the libraries are static, when I compile the demo it inlines all the functions into the executable. This makes for a very large executable, but luckily it has symbols, so for that I'm grateful.<br />
<br />
So I wasn't really sure where to start, except for finding if it even worked with textures. All of the demos are built into a single executable with a menu system for viewing the various examples.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLj8-fC9EAts6P1H0a5hVXKDwpTtdf8whest_kISuwmwCUKQHT04ihUGTQZhKbF2QV1vRR5KwyrGZhQtlT_d3CD7-CdfrD2HDXUfSOzWuR1BeAuG08D5zp6jIohHETBIyOJiN14BaVeao/s1600/havok.menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLj8-fC9EAts6P1H0a5hVXKDwpTtdf8whest_kISuwmwCUKQHT04ihUGTQZhKbF2QV1vRR5KwyrGZhQtlT_d3CD7-CdfrD2HDXUfSOzWuR1BeAuG08D5zp6jIohHETBIyOJiN14BaVeao/s320/havok.menu.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
The example menu</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The 'Animation/Api/Blending/Additive' example is actually one of the demo's that I found to load textures. Here's, what I assume will be, my next target for modification. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6KlcNYv2w24evtmCH1XCsvvzjR7BP04yotup8xivf2BHrzXbPaT0mn2OUCiZ7B3ZbSJeZZ5LJDkXAZQgpZ7COSnd8fvuAlvOEGthQMnHuxhoOVJ987NIuW2eU_L9ETw1897ZJ3gXUeao/s1600/havok.animation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6KlcNYv2w24evtmCH1XCsvvzjR7BP04yotup8xivf2BHrzXbPaT0mn2OUCiZ7B3ZbSJeZZ5LJDkXAZQgpZ7COSnd8fvuAlvOEGthQMnHuxhoOVJ987NIuW2eU_L9ETw1897ZJ3gXUeao/s320/havok.animation.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Just look at her, with her face, I know she secretly wants to be red.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The source for the demo's project is laid out exactly as the menu system, so it's easy to find the code for the above example. The demo does some basic things to render the above. First it loads scene information (background etc). It does this by reading in the hkScene.hkx file and then converts it to it's internal 'scene' representation in it's environment. Next it loads the 'rig' which is another hkx file. I didn't know what a rig was so I asked my friend. He told me that the rig is basically the skeleton of the model for animation. Next it loads the animation information and does something with that (not really sure). Finally, it loads the skin file. Here's that bit of code.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG3zO3U98TMAa_A297ZWWVyX79WBAaDQ4m5GoUj-iaxS5afx4sictye6hR976mPfJxXm_pPVNlBUSl3EtTZRusbmWjRR1dCqCuoMuFqqDBrWGOguOV853WtSihaJ48l-s_b1rhP8OcJtc/s1600/havok.load.skin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgG3zO3U98TMAa_A297ZWWVyX79WBAaDQ4m5GoUj-iaxS5afx4sictye6hR976mPfJxXm_pPVNlBUSl3EtTZRusbmWjRR1dCqCuoMuFqqDBrWGOguOV853WtSihaJ48l-s_b1rhP8OcJtc/s320/havok.load.skin.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
The skin being loaded, and doing stuff.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Yeah, that, makes very little sense to me. I'm not stupid, I realized the engine would encapsulate the rendering, but I was hoping there'd be at least some clear references on rendering or DirectX or <b>something</b>. OK, so I figured that all of the functions and data that <b>I'm</b> concerned with is probably in one of the 300 lib and header files. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Before that, I decided to load up the executable in IDA Pro to see if I could find any references to DirectX. First, I checked out the imports section of the file and found.... absolutely no references to DirectX. Infact, all I did find was references to OpenGL. But as you can see from the first menu image above, they clearly state that it is using DirectX9 shaders...? So after being stumped for a while I looked at the functions list for any DirectX stuff. All I found was various DirectX matrix and vector functions, but nothing I was familiar with seeing.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8nf9_EVZ8PvrEdIxBBHDJK9Qc8sIWXfAgj3nval3pSJ3rlS3TOpWfaOdFSpe8xKHDdzSvFSC_liNqTb5cgXAB6FZM_6HnZYdAVvtp58rJzy9Z81pTQI1vcNBAjV0Y_v0d9ke-wptlWrQ/s1600/havok.dx.ref.ida.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="177" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8nf9_EVZ8PvrEdIxBBHDJK9Qc8sIWXfAgj3nval3pSJ3rlS3TOpWfaOdFSpe8xKHDdzSvFSC_liNqTb5cgXAB6FZM_6HnZYdAVvtp58rJzy9Z81pTQI1vcNBAjV0Y_v0d9ke-wptlWrQ/s320/havok.dx.ref.ida.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
The OpenGL imports and limited DirectX functions</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So going back to my original idea of looking at the lib files, I go to the lib directory and see if I can find anything related to DirectX, which I did.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBAxKojIcpNYLqAwL131UYYpr3sgIMX47FbFQ75qmQ9Ffb1SxljwPkGsgtNCwrollMQKcr2GwTBGL1ofr0HfzKe2390nnvf49beQUK1vAFAMhXwmNtjbD_pIg38O6G6hdifdkU32i70Es/s1600/dx9s.lib.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBAxKojIcpNYLqAwL131UYYpr3sgIMX47FbFQ75qmQ9Ffb1SxljwPkGsgtNCwrollMQKcr2GwTBGL1ofr0HfzKe2390nnvf49beQUK1vAFAMhXwmNtjbD_pIg38O6G6hdifdkU32i70Es/s320/dx9s.lib.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
The static Havok dx9 library</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So I loaded the hkgDx9s.lib file in IDA and was presented with the below screen.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiO3Eo-B4KWRO1ycggdS6jYe_WcLfdo8GWucdSec8fLk8Y0D6sKZkJHrGDfJ1ReZmWE5_wvqfYInKAKRq0CFMi25UyHZ1Poy7K_iTXWtWRGLacsyPFOoAktUEEb3T45TsxcoeyjMjgpeaE/s1600/hkgdx9.lib.ida.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="253" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiO3Eo-B4KWRO1ycggdS6jYe_WcLfdo8GWucdSec8fLk8Y0D6sKZkJHrGDfJ1ReZmWE5_wvqfYInKAKRq0CFMi25UyHZ1Poy7K_iTXWtWRGLacsyPFOoAktUEEb3T45TsxcoeyjMjgpeaE/s320/hkgdx9.lib.ida.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Dx9s's objects</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Ok... that's not easy to work with because I can only load one 'obj' per IDA instance. After going through a number of objects I found there was still no references to DirectX functions. So I'm still continuing my search to try to figure out how exactly they wrapped the DirectX stuff. I just need to play a bit more and probably load it in Visual Studio's debugger and shake it to see what falls out. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I however, will leave that for the weekend.</div>Isaachttp://www.blogger.com/profile/10585942371837479099noreply@blogger.com0