Tuesday, October 29, 2013

Windows DLL Injection used for good not evil

Dll Injection


Dll Injection is a procedure for "hooking" into an already running peice of codes memory space.  So as to spy on or replace functionality.  This post serves to outline my open source project that demonstrates dll patching.  You can find the source code for this post on GitHub


slimhook

Demonstration of dll injection. As well loading .net runtime and calling .net code. Example hijacking d3d9 dll and altering rendering of games.
This project has 2 goals. The first is to have a simple clean interface for performing DLL injection on a windows shared library. The second is to load and execute your custom code in the .net runtime.
Last this project puts these 2 concepts together an performs a DLL injection on a direct3d video game. It then deals with the d3d driver using the SlimDX framework in .net. In this simple example we turn your triple A PC game graphics into “toon” style shading. Which is to say, we reduce the color space significantly using a technique described here: http://en.wikipedia.org/wiki/Posterization

Requirements:

  • N-CodeHook: http://newgre.net/ncodehook This is included in this project since there is a free license to do what you want with it. N-CodeHook is based on Microsoft detours(http://research.microsoft.com/en-us/projects/detours/).. but is completely free. The main advantage to N-CodeHook is the inline patching takes care of your “trampoline”. More info on this is availabe here: http://newgre.net/node/5
  • SlimDX SlimDX is a free open source framework that enables developers to easily build DirectX applications using .NET technologies such as C#, VB.NET, and IronPython. http://slimdx.org/ You need to goto the site and download the latest 4.0 runtime version of the library in order to run the demo code.

There are 3 projects in the solution.

  • inject.prog (Native C++ dll) This is the native C++ dll that will perform the dll injection on the target process. This is also responsible for loading the .net runtime and registering the function callbacks
  • SlimHook3D (C# .net) This is the code we want to execute in the targeted applications memory space. In the case of this demo we require SlimDX and perform graphics operations on the frame buffer of a hooked video game.
  • WinHookApp (C# ,net) Simple WinForm application that allow you to put in the process ID of the target process. This will then start the dll injection process.

How it works

The WinHookApp includes “System.Runtime.InteropServices” to load the symbols from our inject.dll. This can be seen with the following code
[DllImport("inject.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
internal static extern int Inject(int pid, StringBuilder amsBase);
Here we are loading the function that takes to parameters. The PID of the process we want to inject and the assembly base for the .net assembly that we want to load.
Once the inject function is called __declspec(dllexport) int WINAPI Inject(int pid, wchar_t* asemblyBase)
We start the process of DLL injection. We intend to inject the same dll we are executing from, namely inject.dll.
We start by getting a handle to the kernel32 lib
HMODULE hKernel32 = ::GetModuleHandle(L"Kernel32");
Next we call OpenProcess on the process we are trying to inject
HANDLE hProcess = ::OpenProcess( PROCESS_ALL_ACCESS,FALSE, pid );
Next we allocate memory inside that process with enouch room to hold the path to this library
pLibRemote = ::VirtualAllocEx( hProcess, NULL, sizeof(szLibPath), MEM_COMMIT, PAGE_READWRITE );
Now we write the path to this lib in the memory we just allocated.
::WriteProcessMemory( hProcess, pLibRemote, (void*)szLibPath, sizeof(szLibPath), NULL );
From here we create a remote thread that will call "LoadLibraryA" passing it the location of the path we just wrote
hThread = ::CreateRemoteThread( hProcess, NULL, 0,(LPTHREAD_START_ROUTINE) ::GetProcAddress( hKernel32,"LoadLibraryA" ),pLibRemote, 0, NULL );
We now should have this dll loaded into the remote process. The next thing we need to do is call a method in our dll. In this case we want to call "HookD3d9". We first get the address of the function.
FARPROC hookProc = ::GetProcAddress( hLoaded,"HookD3d9" );
Now we load the parameters to the function in the same manore that we did before. This parameter will be the base path for the .net dll asembly.
::WriteProcessMemory( hProcess, pLibRemote, (void*)asemblyBase, sizeof(szLibPath), NULL );
We now calculate the offset to our function "HookD3d9" and call the function with passing in the parameter.
DWORD offset = (char*)hookProc - (char*)hLoaded;
myfile<< std::hex << "Offset: " << offset <<std::endl;

  // Call the real action now that we are loaded.  We can not do anything interesting from the dllMain so we need another exprot to call
  DWORD entry = (DWORD)hLibModule+offset;
  myfile<<"Create Remote Thread 2 at entry: "<< std::hex << entry  <<std::endl;
  HANDLE hThread2 = ::CreateRemoteThread( hProcess, NULL, 0,(LPTHREAD_START_ROUTINE)entry, pLibRemote, 0, NULL );
We now will be executing "HookD3d9" inside of the other process.

Loading and running the .NET runtime

I will save this for a future post ....

Friday, October 25, 2013

android scala gl



android scala gl

Android OpenGL ES 2 / draw utility library written in scala
Link to source code on GitHub

Overview

This project serves to wrap up some common functionality regarding drawing to the screen on the Android platform. I am also fairly new to the scala language and have been very impressed with what I can do with it so far. I hope to continue to add more usefull utilities as I encounter a need for them.

Features

I will try to keep adding to this list as I go. For now here is a short list of features:
  • Simple OpenGL drawable class hierarchy
    • Includes Triangle, Square, Line, Sprite class
  • Simple way to extend functionality via shaders
  • DRY (Do not repeat yourself)

Example Usage

val texInfo = Drawable.loadGLTexture(imgPath)

val w = 2
val h = 2

val verts = Array(-0.5f*w,  0.5f*h, 0.0f,   // top left
                -0.5f*w, -0.5f*h, 0.0f,   // bottom left
                 0.5f*w,  0.5f*h, 0.0f,   // top right
                 -0.5f*w, -0.5f*h, 0.0f,  // bottom left    
                 0.5f*w, -0.5f*h, 0.0f,   // bottom right
                 0.5f*w,  0.5f*h, 0.0f )  // top right
val color =  Array(1.0f, 1.0f, 1.0f, 1.0f)      
val tex = Array(     0.0f, 0.0f,  // top left
                              1.0f, 0.0f,  // bottom left
                              0.0f, 1.0f,  // top right
                              1.0f, 0.0f,  // bottom left
            1.0f, 1.0f,  // bottom right
            0.0f, 1.0f) // top right

val sprite = new Sprite( verts, color, tex, texInfo.textureId)

Example Projects

I currently use this iib in an Android app "Perspective Correct" that should be out in the google play store soon ~(10/20/2013)
Here is a screen shot of the current app Perspective Correct

Thursday, October 24, 2013

Openfire Plugin Dev / Customization

Openfire Plugin Dev / Customization

Now that I have openfire up and running... the next thing I want to do is to customize it to my needs. The normal way to extend openfire is by way of plugin. This allows you to enjoy future upgrades of openfire while not blowing away your source code additions. Admittedly it took a little more digging that I would have liked to find the right getting started guide.

Im my case I decided to go with using eclipse (Scala IDE). Originally I had hopes of writing my plugins in scala.. but ran into a number of problems there, so in the interest of time decided to continue forward with eclipse java. The first guide you should look at to get setup in eclipse is the following doc. Once you have that setup you may want to look at this one as well regarding building all the plugins.

One of the other things that you will notice is the ability to customize the data storage. The architecture here was really focused on JDBC and a SQL back-end... In my case I am using a graph database store so none of this helps me. Looking a little further into it and seems that replacing the JDBC provider with a custom implementation would not take to long ref here. However in the interest of time I have put it on the list of TODO: and forged ahead. There is however a method that will get us partly there. I will outline the goals and methods for achieving them in the following paragraphs

Goals

The idea here is that I would like to replace the "user" and "roster" aka "buddy" list of openfire with my own graphdb full of FOAF like relations. The next thing is I don't want to be slowed down at this stage in dev... so it is ok to leave some "hacks" in the interest of time and then circle back.

Method

In browsing the Plugins I noticed the "userservice". Here is a bit of text right out of the README

The User Service Plugin provides the ability to add,edit,delete users and manage their rosters by sending an http request to the server. It is intended to be used by applications automating the user administration process. This plugin's functionality is useful for applications that need to administer users outside of the Openfire admin console. An example of such an application might be a live sports reporting application that uses XMPP as its transport, and creates/deletes users according to the receipt, or non receipt, of a subscription fee. 


Perfect... this solves our quick and dirty way of getting our users into the system. Next we just need to deal with the roster... so that we get the proper "presence" requests for users coming on and offline.

Again a bit of digging lead me to the creation of a Custom Roster Item Provider. Here is the documentation that describes how to implement.

With not a ton of code, I was able to write a simple Roster Provider that calls my Scala Play webservice. The webservice of course is a REST Json service wrapper for all the good things stored in the graphdb :)

Few last points

In order to get things to work correctly I had to return roster items using the constructor that takes a domain (for example: jid@mydomain.com). But when creating that user inside open fire we only want to pass in the "jid" portion for the user name. Failing this the two ends will not be linked how you would expect them to be.

Tuesday, October 22, 2013

C# FLV byte stream metadata injector

C# FLV byte stream metadata injector

This post relates to my open source project on github. For source code visit me on git flv-streamer-2-file

flv-streamer-2-file

Project takes and FLV stream coming in from a "raw" source, and could be at any point in the "live" stream.
It then saves the FLV to disk and corrects Metadata to allow for seek operations on stream close.
Is this an FLV Metadata injector? Yes. But this one has been written to address some specific needs. Also I think it could be more useful than a lot of the other ones that are out there. Here are some of the major differences:
  • Written entirely in C# (.net)
  • Avoids usage of “unsafe” code.
  • Handles arbitrary file sizes and streams.
  • Memory efficient.
  • Small code base
  • And of course is open source

Overview

This code was developed to accomplish a specific task, but can be adapted to do a number of things to an FLV file.
My goal was to take an FLV stream … and save that stream to disk while still being able to seek inside the file. This means that you can drop out of the stream at any time and the file will contain the portion of content up to that point. The file on disk will contain the total duration and thus be seekable (tested with VLC).
Here is the general idea. I store the FLV header and meta data. I make sure that there are “placeholder” values for the meta data I want. I then write this out to the head of the file we are saving. I then stream the tag data to disk. I also keep a count of audio and video packets… you could also choose to alter timestamps ect…
When the stream errors our or has reached the end. I close the file and then go back in to the head to alter placeholder values. In my case the “duration” or total time of the file in seconds will allow players to now seek in the file.

Usage

The solution consists of 2 projects:
  • FlvStream2File (class library)
  • ConsoleTest (example app)
Compile the FlvStream2File. This is the only project required to use in your application. To use the test app.. simply compile and in a console window you can run:
>ConsoleTest.exe “path to infile.flv” “path to outfile.flv”
This will read in the source FLV and produce an output FLV with the correct duration in the metadata (thus it will allow seek operations)
If you run in the debugger you will also get a lot of useful output via the “Debug.Write” (System.Diagnostics)
Here is an example of how to use the lib.
using(FlvStream2FileWriter stream2File = new FlvStream2FileWriter("out.flv"));
{
  // keep adding bytes to the file (choose a block size)
  while(bytedata){
    stream2File.Write(buffer);
  }

  // finish write and fix flv header.
  stream2File.FinallizeFile();
}

Refrences

Here are some of the features of the more full featured and closed source version of FLV Metadata injector http://www.buraks.com/flvmdi/
Here is some good information around FLV file format
Also you will need to know a little bit about “Action Message Format” (AMF).

Expanding on this

My needs were specific, but the code can be adapted very easily to handle any of the other functions that you see in closed source projects such as FLVMDI

Ideas, Questions, Comments?

Just message me and I will try to help.

Monday, October 21, 2013

CandyJS and OpenFire configuration hell

CandyJS and OpenFire configuration hell

In my last post I got a web based client up and running with facebook chat. This used a BOSH server called punjab. This service acts as a proxy to the actual XMPP server for a web based client. This is required since we lack implementation details for the protocol at the browser level.

When riding on top of facebook chat you quickly realize that there are a number of limitations to 3rd party client. The largest one in my opinion been the lack of group chat support. If you to have been thwarted by this lack of support you can help by directing your request for group support in the API to the Facebook XMPP Developer Relations.

To build in our own support for this we will now need to host our own XMPP server. This is what the following article deals with... all the problems I had one a windows server.

First off ... given the choice I would implement the following on a linux based platform.. but this document may prove useful to someone in either case.

Choose your XMPP server I went and downloaded openfire, and open source apache licensed server. On windows this was an exe installer and a real breeze to install. Once installed you can login via a browser http://localhost:9000 and view / admin the settings.

The first thing that threw me a bit was not knowing that BOSH is integrated right into the openfire server. I originally though that I might have to use my punjab service to form a connection to openfire as well. This is wrong... your BOSH openfire service should be enabled and running on port 7070.

Now that we have our XMPP server up and running we will need to create a test client to connect to it. For me I choose to go with candyjs.

Configure Candy - So download and extract the candy files and example... looking at the documentation I did a configuration like the following.


Candy.init("http://localhost:7070/http-bind", {
  core: {
       debug: true,
       autojoin: ['name@conference.yourdomain.com']
   },
   view: { resources: '/assets/res/candy/' }
});

Candy.Core.connect('user@yourdomain.com','password');


I am developing my web framework in Scala using Play Framework... which like any development server runs on some higher port number (ex: 9000).
This gave me CORS errors saying that my server running on port 9000 is unable to communicate with the openfire server. No problem I rember seeing server settings in openfire to configure CORS. As it turns out I already had the domain set to properly. I tried a number of things to get this working but it always seemed to fail. No problem candy had provided documentation on HTTP Procy Configuration.

Proxy Setup - First thing I tried to do was to configure IIS using the URL rewrite module. This got me to a place of frustration as the "test" methods they provide claimed that it was working while I was unable to get the URL rewrite to perform in my browser.

Rather the fight with M$ I decided to just run the simple node.js proxy. But first off needed to shut down IIS. Going into the services tab a stoping the "World Wide Web Publishing" service should have been all that I need to do... but I failed to free up port 80. What made it worse was that `netstat -a -b -n` refused to tell me the process id that was bound to the port (as if this somehow provides a layer of protection?). With a bit more digging I wound that I also needed to shut down a service called "Web Deployment Agent". This did the job and freed up port 80.

Node.js config - now that I could bind node to port 80 I should have been off to the races, and indeed it looked that way for a while. I created the service as instructed on the candy HTTP Proxy Configuration

var http = require('http');
 
http.createServer(function(request, response) { 

 if(request.url === '/http-bind/') {
  var proxy_request = http.request({
   host: 'yourhost.com',
   port: 5280,
   path: '/http-bind/',
   method: request.method
  });
  
  proxy_request.on('response', function(proxy_response) {
   proxy_response.on('data', function(chunk) {
    response.write(chunk, 'binary');
   });   
   proxy_request.on('end', function() {
    response.end();
   });
   response.writeHead(proxy_response.statusCode, proxy_response.headers);
  });
  
  request.on('data', function(chunk) {
   proxy_request.write(chunk, 'binary');
  });
  request.on('end', function() {
   proxy_request.end();
  });
 }
 
}).listen(80);

So now my candy js configuration had the simple connection like this

Candy.init("http://localhost:7070/http-bind/", ...


Things seemed to be good on first request to the service and then hang on any further requests... grrrr!
Again after digging around I found a better way to implement the node.js proxy service using nodejitsu node-http-proxy


npm install http=proxy


Since I did not care about routing my request... I just wanted to test if this would work.. I wrote the simplest proxy I could think of.

var http = require('http'),
    httpProxy = require('http-proxy');
//
// Create your proxy server
//
httpProxy.createServer(7070, 'localhost').listen(80);


This now finally worked and candy connected properly to openfire.
This is a quick and dirty approach to getting things up and running... but I hope this helps someone else navigate around some of the bs involved and will allow you to get right to the fun stuff... coding.

Thursday, October 17, 2013

Facebook Chat via Punjab Bosh and XMPP

Facebook Chat via Punjab Bosh and XMPP

I recently setup a web based facebook chat and found a number of problems with the information provided on the web on how to do this. This post serves as a reminder to myself and hopes to help others in my situation

Here is a quick diagram on the technology stack

Steps to making a web based client talk through facebook chat

First thing to understand is that you will not be able to talk to facebooks (somewhat XMPP compliant) server directly through your web browser. You are going to have to go through and intermediary service known as a BOSH server. Some more information on BOSH here.

Step 1: Setup and configure your BOSH service. In doing a bit of research I found that most people are using punjab. Punjab is written in python and runs on top of Twisted, here are the steps to getting your environmant setup.

On the server you want to run the BOSH service:
  • Download Python 2.7 here. (I have heard of problems with the above stack in 3.3)
  • Next (and yes this is required) download and install pyOpenSSL for python 2.7. Download link here.
  • Now you need to download and setup Twisted.
This is your environment to allow you to run punjab (the BOSH service) correctly.

Step 2:We need to now get the latest version of punjab from github. Clone or uncompress the file achieve and open a terminal window window into the directory.

Now we need to setup the service in a way were we will be able to talk to facebook. Note: you will require SSL certs. There are a number of examples of people using MD5 hash to connect to facebook and none of these worked for me. I am not 100% sure but I think you may no longer be able to connect in this manor... you therefore require SSL keys.

Create and edit a file in the punjab folder. I called mine "punjab.tac". Below is the contents of my file

# punjab tac file from twisted.web import server, resource, static
from twisted.application import service, internet
from twisted.internet import reactor, ssl

from punjab.httpb import Httpb, HttpbService

root = static.File("./html")

bosh = HttpbService(1)

root.putChild('http-bind', resource.IResource(bosh))

site = server.Site(root)

application = service.Application("punjab")
internet.TCPServer(5280, site).setServiceParent(application)

#
# RMW adding TLS support for Facebook chat/xmpp support
#
sslContext = ssl.DefaultOpenSSLContextFactory(
'PATH_TO_KEY_FILE.key',
'PATH_TO_CERT_FILE.crt',
)
reactor.listenSSL(
5281,
site,
contextFactory=sslContext,
)


# To run this simply to twistd -y punjab.tac
# To run in debug mode twistd -n -l - -y punjab.tac


You should now be able to start the service with the command `twistd -y punjab.tac`
When the service starts for me I am asked for the passphrase for me private key... once I enter this I see the following output
2013-10-16 10:14:32-0700 [-] Log opened.
2013-10-16 10:14:32-0700 [-] twistd 13.1.0 (C:\Python27\python.exe 2.7.3) starting up.
2013-10-16 10:14:32-0700 [-] reactor class: twisted.internet.selectreactor.SelectReactor.
2013-10-16 10:14:32-0700 [-] Site starting on 5280


Step 3: Connecting to facebook with our minimal web client application.
Next you are going to need to setup your facebook application. Follow this guide if you do not already have your facebook app setup.
Take note of both your AppId and your AppSecret. You will require both of these in the html client.
Now you can download my sample HTML application from github.
You will need to edit the APP_ID and APP_SECRET in the html file. Also you may need to change the location and/or port for your BOSH server. Right now it is setup for http://localhost:5280/http-bind

Note: You would not want to share your APP_SECRET in production release

Here is a final screen shot of the simple app.