tag:blogger.com,1999:blog-26963785563827622782024-03-16T11:51:55.325-07:00Simons Codessimonzackhttp://www.blogger.com/profile/16300696271271323597noreply@blogger.comBlogger10125tag:blogger.com,1999:blog-2696378556382762278.post-6053016962575160392015-02-16T23:30:00.001-08:002015-02-17T02:21:11.217-08:00Running debuggable tests & coverage on the same karma server<p>Karma is one of the more popular javascript testing frameworks. But so far, there has been no option to run debugging & coverage on the same server. This <a href="https://github.com/karma-runner/karma/issues/630">issue</a>’s been sitting on github for some years.</p>
<p>The main issue is that karma uses istanbul under the hood for coverage, which does not support source maps. Furthermore, due to istanbul’s detailed branch coverage, debugging, even if it were possible, would be rather slow. This appears to introduce the need for running two karma instances, one configured for debugging, another for coverage.</p>
<p>But there is a much simpler way. What if we were to include both builds within the same page? This configuration is too complex for karma’s build system to support without writing additional plugins, but hey, why not use the popular nodejs build systems directly? Here’s a simplified setup of mine which does exactly this:</p>
<pre><code>var gulp = require('gulp');
var concat = require('gulp-concat-util');
var istanbul = require('gulp-istanbul');
var watch = require('gulp-watch');
var karma = require('karma');
var path = require('path');
gulp.task('test', function(){
karma.server.start({
frameworks: ['qunit'],
reporters: ['coverage', 'progress'],
autoWatch: false,
files: ['dist/**.js']
});
watch('**/*.js', {}, function(){
gulp.src('**/*.js')
.pipe(concat.header('if(window.location.href.endsWith("debug.html")){'))
.pipe(concat.footer('}'))
.pipe(gulp.dest('dist/test'));
gulp.src('**/*.js')
.pipe(istanbul())
.pipe(istanbul.hookRequire())
.pipe(concat.header('if(!window.location.href.endsWith("debug.html")){'))
.pipe(concat.footer('}'))
.pipe(gulp.dest('dist/cover'))
.on('end', function(){
// monkey-patch to get rid of stdout
var http = require('http');
var request = http.request;
http.request = function(options, response){return request(options);};
karma.runner.run({});
http.request = request;
});
});
open('http://localhost:9876/');
});
</code></pre>
<p>The concat magic determines which script to run based on the current url (<code>debug.html</code> is, quite simply, karma’s debug page), and <code>run</code> fires off the signal to run tests.</p>
<p>If you’ve been reading carefully, the monkey-patch may appear to be rather confusing, but that’s due to <code>karma.runner.run</code> outputting the test results to the console, which is what the server’s doing at the same time. We wouldn’t want to have two outputs writing over each other, would we? (bug’s filed <a href="https://github.com/karma-runner/karma/issues/1314">here</a>).</p>
<p>Happy debugging!</p>simonzackhttp://www.blogger.com/profile/16300696271271323597noreply@blogger.com0tag:blogger.com,1999:blog-2696378556382762278.post-24570640992269766622014-12-30T05:22:00.001-08:002014-12-30T05:24:57.864-08:00Writing a JS sol parser to cheat idle farmer<p><a href="http://www.newgrounds.com/portal/view/632535">Idle farmer</a> was a game I discovered a few days ago which was one of the more enjoyable incremental games. Unfortunately, farming in the game is slow and tedious, and only gets worse over time. I decided to speed it up a little.</p>
<p>Scanning variables in cheat engine yields no results, for reasons I don’t know (and haven’t investigated), so I decided to look at the sol data. Converted to json, it looks something like this:</p>
<pre><code>{
"dataos": "gJE5706:321250LB<9Â ... "
}
</code></pre>
<p>Clearly, this is some form of encrypted data. I hooked the game up in the <a href="http://www.free-decompiler.com/">JPEXS</a> decompiler, and after some digging, found these two classes related to save data handling:</p>
<pre><code>DataSaver
DatosGuardados
</code></pre>
<p><code>DatosGuardados</code> is the class which handles save data encryption/decryption, and <code>DataSaver</code> is the one which convert’s it into an actionscript format.</p>
<p>Something new here which isn’t usually seen in other flash games is it’s use of the <code>haxe</code> serialization/deserialization routines. So I took the lazy route to write a parser in js, the closest language to both <code>haxe</code> and <code>actionscript</code> which is the easiest to hack with.</p>
<p>There’s no existing sol parser for js, but sol is really just a thin container around amf3, and there already are some <a href="https://github.com/infomaniac-amf/js">libraries</a> for dealing with it, so this wasn’t so hard.</p>
<p>Next came the deserialization part, which involved copy pasting <code>DataSaver</code> and <code>DatosGuardados</code> and manually converting them to haxe (the language similarities meant that this was relatively easy work).</p>
<p>Then came the hard part. The decrypted data was not unserializable, nor human readable. There weren’t any avm bytecode debuggers to help either. How are we going to know what fucked up?</p>
<p>But luck is on our side, and the actionscript <code>trace</code> function comes to the rescue. We can basically print anything by inserting the following in the avm code:</p>
<pre><code>findpropstrict Qname(PackageNamespace(""),"trace")
getlocal 1
callpropvoid Qname(PackageNamespace(""),"trace") 1
</code></pre>
<p>and enabling flash player tracing in <code>mm.cfg</code>.</p>
<p>After printing some loop variables and inspecting the code which clearly didn’t look right, the bug became apparent:</p>
<pre><code>_loc14_ = 0;
while(_loc14_ < _loc6_) {
_loc14_++;
_loc15_ = _loc14_;
_loc11_ = param1.charCodeAt(_loc13_ - _loc15_ - 1);
_loc2_.b = _loc2_.b + String.fromCharCode(_loc11_ - _loc10_);
}
</code></pre>
<p>(<code>param1</code> is the input string, looks like an off-by-one here)</p>
<p>The assignment translates to the following, can you spot the error?</p>
<pre><code>getlocal 14
inclocal_i 14
convert_i
setlocal 15
</code></pre>
<p><code>getlocal</code> pushes local 14 onto the stack, <code>inclocal_i</code> doesn’t modify the stack, so <code>convert_i</code> is still using the old value - <code>_loc14_</code>, <em>not</em> <code>_loc14_ + 1</code>.</p>
<p>The fix is simple:</p>
<pre><code>_loc14_ = 0;
while(_loc14_ < _loc6_) {
_loc15_ = _loc14_;
_loc14_++;
_loc11_ = param1.charCodeAt(_loc13_ - _loc15_ - 1);
_loc2_.b = _loc2_.b + String.fromCharCode(_loc11_ - _loc10_);
}
</code></pre>
<p>Now we can finally deserialize, pretty print everything in json, make the exporter, and be done with it!</p>
<p>And if you feel like cheating today, <code>git clone https://github.com/simonzack/idle_farmer_parser</code>.</p>
<p>Oh, and if you’re wondering about the strange key names, they (and the game) are written in spanish.</p>simonzackhttp://www.blogger.com/profile/16300696271271323597noreply@blogger.com0tag:blogger.com,1999:blog-2696378556382762278.post-85661853892323837112014-12-24T22:51:00.001-08:002014-12-24T22:52:41.957-08:00Disabling smooth scrolling on wordpad<p>I’ve always been annoyed by smooth scrolling, and if you’re reading this blog post, you’re probably annoyed too. Wordpad on windows has smooth scrolling on, and a quick browse through the settings turns up no option to disable this. Time to debug!</p>
<p>A quick browse through the modules list (windbg’s <code>lm</code>) shows up something interesting, <code>msftedit.dll</code>, which a quick googling shows that it allows applications to embed rich text text-boxes. This is the dll for the latest version of the rich text edit control, <code>v4.1</code>. Previous versions include <code>riched20.dll</code> and <code>riched32.dll</code>.</p>
<p>Since that is basically what wordpad is doing, could wordpad simply have embedded a rich text box in it’s window? Breaking on <code>msftedit!RichEditWndProc</code> shows that this is indeed the case, where scrolling the text box breaks on this routine, with <code>WM_MOUSEWHEEL</code> as the <code>message</code> parameter.</p>
<p>Rich edit boxes are not only used under wordpad, but all over the place. Examples include <a href="http://code.google.com/p/tortoisegit/">tortoisegit</a> and windbg.</p>
<p>Digging a bit further, we see that the routine that starts the scrolling is the following:</p>
<pre><code>0051ee3c 5ec19ed8 Msftedit!CDisplay::SmoothVScroll
0051ee60 5ec0d6de Msftedit!CMagellan::MagellanRollScroll+0x98
0051eea8 5ebb8f66 Msftedit!CTxtEdit::HandleMouseWheel+0xee
0051f028 5ebe38e5 Msftedit!CTxtEdit::TxSendMessage+0xe15
0051f918 76de62fa Msftedit!RichEditWndProc+0xa31
</code></pre>
<p>Fortunately for us, <code>SmoothVScroll</code> is open sourced in windows CE, which helps in analysis. But going through each of the methods starting from <code>HandleMouseWheel</code>, we see that there are a couple of places the call to <code>SmoothVScroll</code> can be skipped, depending on some flags. Unfortunately none give us the desired behaviour. Some flags control zooming, and others disable scrolling entirely.</p>
<p>The relevant header file defines <code>SmoothVScroll</code> ‘s as:</p>
<pre><code>VOID SmoothVScroll ( int direction, WORD cLines, int speedNum, int speedDenom, BOOL fMouseRoller );
</code></pre>
<p>We can see some speed arguments here. Patching <code>speedNum</code> to 1 and <code>speedDenom</code> to 50, to give a speed of <code>1/50</code> instead of the default <code>3/1</code>, does give us instant scrolling behavour, But <code>SmoothVScroll</code> also has a kind of acceleration effect, where if we scroll longer using the mouse wheel the scrolling speed will accelerate. This can be rather annoying while editing text.</p>
<p>There is a way to skip the call to <code>SmoothVScroll</code> entirely, and without going into internal functions, by hooking <code>RichEditWndProc</code> and sending <code>WM_VSCROLL</code> when <code>WM_MOUSEWHEEL</code> is received. The former occurs when we press the up and down buttons on the scrollbar.</p>
<p>We can also scroll faster by sending it more than once.</p>
<p>I implemented the above hooks in <a href="https://github.com/simonzack/rich_edit_scroll">rich edit scroll</a>, which uses <a href="https://github.com/jarredholman/minhook">minhook</a>, <code>SetWindowsHookEx</code> and friends. Run <code>install.bat</code> to run it on startup, and smooth scrolling will be gotten rid of for good.</p>
<p>Rich edit scroll allows configuring which applications to hook as well as scrolling speed. Hooking is opt-in due to exe protectors often checking whether <code>LoadLibrary</code> is hooked, which is sometimes necessary, in the case of windbg. That can cause them to stop working.</p>simonzackhttp://www.blogger.com/profile/16300696271271323597noreply@blogger.com12tag:blogger.com,1999:blog-2696378556382762278.post-55270853060935279782014-10-22T11:24:00.000-07:002014-12-24T23:06:22.174-08:00Consolidating orphaned vmware snapshot vmdks<p>VMware often leaves behind orphaned vmdks after snapshots are deleted. There is no clear way to consolidate this into the main vmdk file from the gui. But by googling around, it appears that people are fixing this by cloning a virtual machine.</p>
<p>But there is a much better and less intrusive method. Internally, vmware clones a virtual machine by using <code>vmware-vdiskmanager.exe</code>, which can be found in the vmware installation directory. It appears that the following command will consolidate the snapshot in the vmdk to a different one (beware, it does not accept paths containing spaces, and will give some spurious error messages).</p>
<pre><code>"C:\Program Files (x86)\VMware\VMware Workstation\vmware-vdiskmanager.exe" -r main-000002.vmdk -t 0 C:\test.vmdk
</code></pre>
<p>The story should’ve ended here, but vmware-vdiskmanager.exe gave me a spurious error message:</p>
<pre><code>Failed to convert disk: One of the parameters supplied is invalid (0x100003e80).
</code></pre>
<p>Googling this gave me dozens of dozens of problems associated with this generic error message. But vmware-<code>vdiskmanager.exe</code> does in fact have logs, located in the <code>%temp%\vmware-%username%</code>. Scrolling through these logs, <code>vdiskmanager.log</code>. Scrolling through this, some less generic but not any less confusing error message showed up:</p>
<pre><code>DISKLIB-LIB : DB: incorrect set operation 'consolidateDestFileName' = '(null)'.
DISKLIB-LIB : Failed to clone : One of the parameters supplied is invalid (1).
DISKLIB-LIB : DB: incorrect set operation 'resumeConsolidateSector' = '(null)'.
DISKLIB-LIB : Failed to clone : One of the parameters supplied is invalid (1).
</code></pre>
<p>The fields referenced by the error isn’t documented anywhere at all. However, by looking at the snapshot vmdk’s using a hex editor, it appears that these are internal settings within the vmdk files. <code>consolidateDestFileName</code> should point to the main vmdk file, but was missing in the snapshot vmdk file <code>vmware-vdiskmanager.exe</code> choked on. Copying this into the snapshot vmdk file seemed easy enough, but I had no idea what <code>resumeConsolidateSector</code> meant.</p>
<p>Fortunately, it appears that these fields can be restored by creating a new snapshot in vmdk and deleting it. <code>vmware-vdiskmanager.exe</code> finally started working correctly, and I managed to consolidate my snapshots.</p>simonzackhttp://www.blogger.com/profile/16300696271271323597noreply@blogger.com5tag:blogger.com,1999:blog-2696378556382762278.post-60916023022753668032014-10-13T22:17:00.001-07:002014-10-13T22:19:44.327-07:00Firefight TrainerFrom the comments looks like a lot of you are still interested in firefight. Old games are still the best!<br /><br />I did some work over the years and tidied some of it up last few weeks ago to create a cheat engine trainer.<br /><br />Download the latest version of cheat engine, and the <a href="https://github.com/simonzack/firefight_trainer/archive/master.zip">trainer</a>, attach to the process, and fire it up.<br /><br />Enjoy!<br />simonzackhttp://www.blogger.com/profile/16300696271271323597noreply@blogger.com0tag:blogger.com,1999:blog-2696378556382762278.post-13496535099197024742011-08-21T19:45:00.000-07:002011-08-21T19:47:11.835-07:00Patching utorrent slow ipfilter loadingWhen utorrent's ipfilter.dat, a file which filters out malicious ips in peer swarms, grows large, utorrent hangs at startup<br />
I noticed this when I tried putting some new lists into the filter<br />
<br />
A little reversing uncovers the issue<br />
<br />
The ipfilter.dat ip range format looks like this (for ipv4)<br />
1.2.3.4-5.6.7.8,0,test<br />
<br />
This includes a start, an end, a priority level, and an optional description<br />
<br />
The problem happens after utorrent parses ipfilter.dat, when it attempts to optimize it<br />
It does so by trying to merge all the ip filter ranges together<br />
<br />
the function is layed out like this:<br />
<pre>sort(ipRanges)
for ipRange in ipRanges:
if ipRange overlaps with the previous range:
copy ipRanges[i:] to ipRanges[i-1:]
</pre><br />
when there are many overlapping ranges, the copy operation (a memcpy) becomes very slow<br />
<br />
obviously, when there are no overlapping ranges, the slow down does not occur<br />
<br />
there are many ways to rewrite this, as long as only 1 range is copied every compare, the function will be fast<br />
<br />
Patching this makes utorrent start-up fast again<br />
<br />
I'm not sure if utorrent 3 has fixed this yet, but for those who are still using v2, here's a patch:<br />
http://www.mediafire.com/?tto3p44mwvn5tfx<br />
simonzackhttp://www.blogger.com/profile/16300696271271323597noreply@blogger.com1tag:blogger.com,1999:blog-2696378556382762278.post-55459303119323128222011-06-21T01:50:00.000-07:002011-06-21T01:50:27.975-07:00eset crackme 2011 solutionI've promised to post a solution, so here it is<br />
<br />
the crackme does some simple checking first<br />
<br />
len(name)>=5<br />
len(key)>=0xA<br />
<br />
then it loads an elf file from resources, which doesn't have anything linux-specific except for the file format, so the parts of it used runs fine on windows<br />
<br />
it calls 2 routines from it<br />
<br />
the first routine hashes the username, identified by the genius cryptographist dcoder as cubehash<br />
<br />
this hash is then fed into a big macro laden routine<br />
<br />
it looks big, however when you look at the individual parts it's not that complicated<br />
<br />
inside the big loop:<br />
the first macros reverses the bits of a 64 bit var<br />
the next few calls another macro 32 times, we can simplify it to this<br />
<br />
esi=bitset(local_134,63)?5043443f1755df4d:0<br />
ecx=bitset(local_134,62)?5043443f1755df4d:0<br />
ecx:edi^((esi:ebx^(local_138:local_134<<1))<<1)
simplifying further, it actually calls one macro twice
n=((n>>63)?0x5043443f1755df4d:0)^(n<<1), where n is a 64 bit number<br />
<br />
the last few macros reverse the bits of n again<br />
<br />
this looks very much like crc, in fact, it is a crc64 with a starting value of:<br />
0x3537000000003735<br />
and a polynomial of:<br />
0xb2fbaae8fc22c20a (this is the bit reversed 0x5043443f1755df4d)<br />
the final value is xored with:<br />
0x6b3e997a6008e054<br />
<br />
a constant string and our key is fed into this routine, then compared with the hash<br />
<br />
to reverse this, we simply reverse the crc<br />
<br />
most of eset's crackmes so far needs a certain crc to be reversed, so you better get used to it if you do more :)simonzackhttp://www.blogger.com/profile/16300696271271323597noreply@blogger.com0tag:blogger.com,1999:blog-2696378556382762278.post-59632535249101076682011-06-21T01:37:00.000-07:002011-06-21T01:37:12.368-07:00Getting firefight to work on win7Firefight's a game made by chaos works, in 1996<br />
<br />
Surprisingly it works on windows 7 with little effort, and without the need to use windows compatibility mode<br />
<br />
After a little debugging, the reason it doesn't run on windows 7 (both LOADER.EXE and FIREFGHT.EXE) is because of a bug in the program using SetWindowsHookExA with thread id as null<br />
<br />
The bug doesn't manifest itself under win98<br />
<br />
The thread id value is filled after this call instead of before it<br />
<br />
I didn't dig deeper into this, this probably changed after win98<br />
from msdn: "An error may occur if the hMod parameter is NULL and the dwThreadId parameter is zero"<br />
<br />
there's also a small cd check in FIREFGHT.EXE, patching this makes the game work<br />
<br />
I've uploaded the patched files here, if you need them<br />
http://www.mediafire.com/?omab7605dwwh7ek<br />
<br />
ps.<br />
<br />
if you want to get this game, you could probably find it on the internet somewhere<br />
if not, send me an emailsimonzackhttp://www.blogger.com/profile/16300696271271323597noreply@blogger.com53tag:blogger.com,1999:blog-2696378556382762278.post-84711896136707344772011-05-25T07:13:00.000-07:002011-05-25T07:14:19.469-07:00eset crackme 2011Go check out eset's new 2011 crackme<br />
http://2011.confidence.org.pl/<br />
<br />
It shares some stuff from their 2010 confidence crackme<br />
<br />
I'd rate this 3/10 on a crackmes.de scale<br />
<br />
here's an example name/key<br />
<br />
simonzack<br />
9f6d5eab-dtdlcdp3asalclsatpt1<br />
<br />
will publish a solution here when confidence endssimonzackhttp://www.blogger.com/profile/16300696271271323597noreply@blogger.com7tag:blogger.com,1999:blog-2696378556382762278.post-9494757675513809542011-05-25T07:07:00.000-07:002011-05-25T07:17:25.832-07:00Getting nfs high stakes to work better on win7Years back, I played this game all the time<br />
After playing some of the much more recent shift 2, and failing to get past the drifting (dont have a steering wheel :( ) thought of playing this again, this time on windows 7<br />
<br />
There already exist many good tutorials getting it to work on 7<br />
but there are a few small problems<br />
the patch (v4.50) runs the game using PatchNFS.exe<br />
starting this up always redirects the game to the network play screen, displays an "Unkown error" (network connection failed probably due to server changes in the past 10 years), there are no title movies, and the game needs to mount the iso to play<br />
<br />
So I started looking at the exe to see if I could make some changes<br />
<br />
the main nfs exe: nfshs.exe, is no longer securom protected in the patch, this makes things much easier<br />
<br />
starting up this exe gives us an error message telling what arguments are needed<br />
these are probably passed by the loader PatchNFS.exe<br />
<br />
searching for the movie file locations can lead to where the movie's played<br />
<br />
I found this here:<br />
<br />
mov eax, offset aEatumble_mad ; "EAtumble.mad"<br />
call playMovie<br />
mov eax, offset aNfstitle_mad ; "NFStitle.mad"<br />
<br />
here EAtumble refers to the ea logo, NFStitle is the game intro<br />
<br />
going into the next call tells us there's a flag thats needed to be unset to allow the movie to play (this also starts up the network play)<br />
<br />
after debugging a bit, this flag is set during the arguments parsing<br />
<br />
if the game is started using -PatchRestart, the flag is set<br />
<br />
looking at the parsing a little more reveals that there must be at least 1 argument set for the game to start<br />
<br />
the only other argument is -D3D%d<br />
<br />
I tried starting the game using -D3D9<br />
and there it is, the title screen and logo all back, some of the game graphics options open up too<br />
<br />
now onto the second problem, removing the need to insert the cd<br />
the cd checks are simple to bypass<br />
but after trying to start the game, we are greeted with some sound files not found message<br />
<br />
debugging a bit, the sound files paths are overridden for some file types, located here:<br />
HKLM\Software\Electronic Arts\Need For Speed High Stakes\1.0 SrcDrive<br />
<br />
change the path to whatever your installation path is, copy over the sound and movie files, and the game starts perfectly without the need to mount an iso<br />
<br />
here's the diffs if you need them<br />
F7324 75 > EB<br />
F737C 75 > EB<br />
104045 74CC > 9090<br />
<br />
have fun playing this old classicsimonzackhttp://www.blogger.com/profile/16300696271271323597noreply@blogger.com1