Reverse Engineering RET Homepage RET Members Reverse Engineering Projects Reverse Engineering Papers Reversing Challenges Reverser Tools RET Re-Search Engine Reverse Engineering Forum Reverse Engineering Links

Go Back   Reverse Engineering Team Board > Reverse Engineering Board > .NET Reverse Engineering
FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Display Modes
  #1  
Old 05-11-2011, 02:05 PM
bhpushnslide bhpushnslide is offline
Member
 
Join Date: Apr 2011
Posts: 5
Default Story so far (first time reversing)

Hey All,

I've been reversing a .net game. It's my first time reversing and I just wanted tell the story so far a bit.

I mainly wanted to do this to say that with Google and tenacity you can truly achieve amazing things.

My past programming experience is pretty limited. I've done a few .net bits in the past but mainly some asp.net database stuff. But mostly i do front end php / js development. But even that i've only been doing for a year now (all learnt though Google... No formal training)

But I really wanted to get into reversing and after finding reflector i thought this can't be that hard!

So i picked my target (Online game with .net client that's updated monthly) It's pretty big (around 70 namespaces and about 1000nd classes in each....) and it was protected by smart assembly and obfuscated.

So my first task really was how can I use reflexil to add a few simple logging classes so i can send that data to my "bot" and my "bot" doesn't have to do screen shots etc and OCR to see what's going on..

Great so i started... and hit my first snag.... If i save the file after making modifications with reflexil the exe doesn't work anymore!

Now I spent about 2 weeks solid and trying to find a way around this... I found a few hints about opening the file up in a PE reader or something and overwriting the corrupt data with specific hex values... But that seemed like boring hard work...

I tried things like deSmart and though they were good at deobfuscation.. They also made they also made the exe stop working...

Well I found a really easy way to get reflexil so it would allow me to save.. I'm not ganna say what it is because it's so easy i cant believe it's not posted everywhere, which makes me think maybe people are keeping quiet about it lol. But it's easy enough i can easily "fix" the exe each time a new release is put out and just put my "injected" code back in

So next i started working on adding some logging classes. The problem next was i didn't know IL code... And I couldnt code in C# because the file was still obfuscated and it wouldnt compile if it tried to do the "replace all with code" thing... So i spent another few days just looking at the deobsfacated code in c# then switching to IL and trying to work out how it all works..

After alot of stress and Google abuse I had my "bot" pretty much receiving the data I wanted and now understood IL to an extent.

Anyway's i worked on it for about a week more and suddenly decided that this was a rubbish approach and I should remake my own client that just spoofs the network protocols.

The problem was... I didn't know the first thing about networking in C#.. So after A LOT more time and A LOT more googling i managed to get myself clued up on networkstreams and got my logging classes to log the Byte[] sent and received before they are encrypted and after they have been decrypted..

GREAT! I see packets........ But had no idea what to do next..

After more messing about and Googling i worked out to convert the whole thing to text using the ascii converter.. Which helped alto cos now i had rough idea of what was being sent in each packet.

Few more days of looking into the game code i worked out how the packets were built (well kinda) i worked out that the first 8 bytes are the length of the packet and the next 4 bytes (UInt16) is the packet instruction (i been calling it the opcode?) to tell the client / server what to do. Learning HEX was fun lol..

That's pretty much as far as I've got I've hit a bit of a road block at the moment... (I'm reading the bytes from the server after the BeginRead NetworkStream function.. But I think because that's an asynchronous read i'm reading the data before I've got the full packet.. So if the packets too big i don't get the whole thing. I been trying to log it on the EndRead but I cant seem to access the Byte[] field that was set with BeginRead.... But that just down to me not understanding exactly how asynchronous stuff works in c#.. )

I really wanted to post on here just to say that IMO reverse engineering is the best way to learn a programming language. Who would think that in a few months you can go from little programming knowledge to the start of creating you own reverse engineered game client!

I've been trying so hard not to ask a single question on stuff i've been getting stuck on.. And so far Google has served me well!

But can see me getting stuck on something i can't Google-Solve so i thought id better let myself known on here hahaha.

Sorry if no ones cares btw! lol... But I thought I'd get myself on here and say hi and stuff as i notice this sites had popped up quite a bit in my searching.. And im sure i've got a few good bits of info off here aswell!
Reply With Quote
  #2  
Old 05-11-2011, 04:56 PM
kao kao is offline
Senior Member
 
Join Date: Sep 2007
Posts: 184
Default

Hi and welcome!

It's a great and inspiring story, thank you so much for it! Most people come here and ask (in fact, demand!) ready made solutions for all their problems. You have managed a lot by yourself, and I have a huge respect for that.

About online game reversing.. Based on my experience, figuring out general packet structure is only ~5% of the entire project. The remaining 95% of time is spent figuring out meaning of each packet opcode, what data it requires, what is optional, all the special cases, etc.. Of course, if you are making a simple spam-bot, you need to support just a few opcodes and ignore everything else.

If you want to make a full-fledged bot, I would suggest that you reconsider your approach. I would make external DLL in C# that would contain entire bot functionality. Then I would patch few methods in client, so that it calls my DLL and exchanges necessary information with it. This way I would be able to focus on developing bot instead of reinventing the wheel (=reimplementing game client).

One more thing - .NET assemblies make great targets for reversing. Just decompile few classes, copy-paste it into Visual Studio, fix few references and you have, for example, ready-made network packet handler. Rewriting it all from scratch should be used only a last resort.. But then again, copy-pasting is not much fun...

Cheers,
kao.

P.S. Nitpickers corner - UInt16 size is 2 bytes, not 4..
Reply With Quote
  #3  
Old 05-12-2011, 09:43 AM
bhpushnslide bhpushnslide is offline
Member
 
Join Date: Apr 2011
Posts: 5
Default

hey thanks for the reply!

See for me this is all like loads little puzzles to solve, so if i ask for all the solutions it's not going to be very fun.

and.. DOH on the UInt16 size is 2 bytes thing.. I did know that! honestly haha... But at the time i was looking at "00-01-00-00" and was like o yeah, its the first 2 blocks is a Uint16.. then counted 0,0,0,1 like a fool. But i appreciated being corrected.. Saves me having to carry on writing it wrong!

I'm not trying to do anything like a spam bot.. More just curiosity at the moment, but i'm just hoping to create like my own api for if i do want to do somthing like a trade bot down the line..

So send get player list.. Receive player list.. Show player list in my client etc etc..

I've got it connecting to their server. and i did manage to login by just copy & pasting the outputted bytes from a real login (just saved to a text file and some find replace magic)

I have a nice list I've found in the source of opcode to what looks like the byte[] processor for each message. I'm not sure what way round it works yet (i mean if its for incoming or outgoing messages or both).

At the moment i'm just banging my head trying to workout how i can get the full incoming buffer. It's using the standard .net NetworkStream .BeginRead and then im looking at the where the endread is called. But following all the classes have been a dead end...

Sure i'm missing fundamental, the big problem with jumping in at the deep end lol..

Thanks again for the reply... Wasn't sure how people would reply but i'm glad i posted it

Right my above problem is beating me.. I've been working a solid 26 hours trying to work it out (booked a day off work cos i was so "in the zone" haha)

Can anyone recommend a good forum for a little bit of help / direction on the problem i'm facing (trying to workout how this game deals with large packets... I'm reading all the packets fine if they are small. But when the packets start getting over (a strange 8191 bytes) i'm not getting the whole packet. in fact seems like i'm getting the middle of a packet).

I would go to a standard .net forum. But not sure how people would react knowing what i'm doing.

If people here would be able to help let me know and i'll try and supply as much information as possible

Last edited by Git : 05-12-2011 at 11:42 AM.
Reply With Quote
  #4  
Old 05-12-2011, 10:25 AM
kao kao is offline
Senior Member
 
Join Date: Sep 2007
Posts: 184
Default

The standard answer in this forum would be - decompile your target and look at the code.

Based on your description of problem, it sounds like you're using buffer with size 0x2000 (=8192decimal) somewhere in the code. If the packet is small enough, you process it properly. If packet is bigger, you discard first 0x2000 bytes. But that's just a wild guess.

Any forum will ask you for code that exhibits the problem. You might as well post it here, there are some quite good C# coders on this forum (not me, though! )
Reply With Quote
  #5  
Old 05-12-2011, 10:37 AM
bhpushnslide bhpushnslide is offline
Member
 
Join Date: Apr 2011
Posts: 5
Default

[Please DO NOT quote whole messages, it is unnecessary]

ahhh guru Kao haha thanks for your response! I'm going to give that try in a sec.

I'll give myself another 2-3 hours in the source and see if something pop's up! If not i'll post what i have done to get the results i have and a clearer explanation of the issue

Thanks again .. You in the UK btw? noticed you was online around the UK morning (my morning)

Last edited by Git : 05-12-2011 at 11:43 AM.
Reply With Quote
  #6  
Old 05-13-2011, 06:57 AM
bhpushnslide bhpushnslide is offline
Member
 
Join Date: Apr 2011
Posts: 5
Default

Right, Decided to keep cracking on myself with it and managed to now get a full incoming packet (woop)..

what was causing me issues (and if anyone could help me with this i would appreciated it) is the below:

Ok the full length of my big incoming packet was 26805 bytes.

Now if i use Bitconverter.ToInt32(buffer, 0) it returns the correct 26805 int.. And the first 4 bytes of the packet was B5-68-00-00.

Now where i was caught out was at first i was typing into a online hex to int converter. If i put in 0xB5680000 the answer i get is "-1251475456"

Now i thought maybe it's ignoring the 00-00 at the end. So i put in just B568 but this would give the result 46440.

After a while of messing around i noticed the bytes were backwards! the correct size of 26805 = 0x000068B5.

So my question really is does Bitconverter.ToInt32 take the first 4 bytes, reverse them and then make the hex to int conversion?

If so.. Anyone know why / is this a .net thing that all int's converted to bytes will be reversed?

Thanks for any help!
Reply With Quote
  #7  
Old 05-13-2011, 07:28 AM
kao kao is offline
Senior Member
 
Join Date: Sep 2007
Posts: 184
Default

That's called little-endian format. Almost everything in x86 and x64 world uses that format.
Reply With Quote
  #8  
Old 05-13-2011, 08:01 AM
bhpushnslide bhpushnslide is offline
Member
 
Join Date: Apr 2011
Posts: 5
Default

Thanks again Kao,

I had seen some "isLittleEndian" methods.. So now i know what they are all about .

As this is i guess a little story of my progress thought i would post an update.

Well now i have full sent and received packets. I decided to see what i could do with them. Knowing the opcode a little string search in reflector was very helpful!

So i thought i would try my luck and a just copy the class the opcode was telling me right out of my de-obfuscated source, fixed up any calls to external classes and fed my byte array thought it..

and i got a meaningful array of data out, a nice collection of online payers and their ID's!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump





Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2023, Jelsoft Enterprises Ltd.