samuri25404 Grandmaster Cheater
Reputation: 7
Joined: 04 May 2007 Posts: 955 Location: Why do you care?
|
Posted: Wed Dec 26, 2007 3:04 pm Post subject: [C#] [RELEASE] THE LONG AWAITED OPCODE.DLL (FINALLY) |
|
|
This is a DLL written in C# that can be used to convert opcodes (for example, "mov
[eax+4],ecx" ), to an array of bytes, for whatever purposes (most will be to inject,
but there may be other things).
Also, I know it has bad error handling, but I'll fix that up in the next version (I'm
going to still be working on it after this release, in case you didn't know).
I have also included a sample application used with this to convert scripts to AoB's,
with an optional prefix and suffix (so you can have like this:
prefix:
Code: |
WriteProcessMemory( new byte[] {
|
suffix:
Code: |
}, other parameters);
|
~~~
So in order to use this, all you have to do is follow these simple steps:
1) Load up your project
2) View the Solution Explorer
3) Select "References"
4) Right click it
5) Select "Add Reference"
6) Select the "Browse" Tab
7) Go to the directory where you have my Dll saved
8) Select it
9) Click ok
=D
~~~
Functions:
Code: |
GetBytes
Formalize
AddSpaces
zeReplace
Tokenize
DetermineOpcode
mypredicate
FindAbsOpcode
DetermineR_BWD
GetPTypes
GetParam
zepredicate
InsPrefs
SetMnemonic
ModRMnSIB
DetermineDispType
BinaryToHex
Displacement
Immediate
|
~~~~~
This is the only public thing in the DLL
It is what you call, basically, like this:
Code: |
Opcode.Opcode.GetBytes("mov [eax],ecx");
|
In it, the algorithm for finding the array of bytes is defined.
~~~~~
This is a method used to make things easier to mess with, because some of the methods
in here rely in specific form, and without it will probably crash, or at least produce
an unwanted result.
~~~~~
This is used by the Formalize method, simply to add spaces around something.
~~~~~
This is also used by the Formalize method, so the program can easily replace for
example, "NGE" to just "L", if the string contains it, without a cluttery-looking
source code.
~~~~~
This splits up the string opcode into an array of strings. It would take, for example,
Code: |
mov [ eax + 4 ],ecx
|
(Note the spacing, that would be from the Formalize method)
and would turn it into so:
Code: |
mov
[
eax
+
4
]
,
ecx
|
With each new line representing a new element in the array.
~~~~~
This is used to find the mnemonic (basically the string, like in the previous opcodes,
"mov" is the mnemonic), and find where it is in the array of opcodes. It uses
Array.Find(), which is an incredibly fast way of doing things (I made a post about it
in the regular section).
~~~~~
This is simply a predicate to find the correct opcode for DetermineOpcode.
~~~~~
This is a method to find the actual opcode, the one that matches the parameter types
exactly. If none match, then it throws an error, and quits. If one does, then it adds
those bytes to a seperate list to be added when the prefixes are done. This also
includes adding in the +rb, +rw, and +rd things.
~~~~~
This method returns a value for the OpcodeInfo's rb, rw, and rd (which take a simple
value and add them to the array of bytes).
~~~~~
This is a method called by FindAbsOpcode, to help in the finding of the opcode. It
determines the parameter types from the tokens, then sets them to the private global
vars, which are used in the predicate when looping through.
~~~~~
This is a method used to determine the types of parameters a string array (the tokens)
are (like r32 for example).
~~~~~
Another simple predicate, called by FindAbsOpcode, to find the correct opcode.
~~~~~
This method determines which Instructional Prefixes are needed in the array of bytes,
and adds them in. Then, it adds in the actual opcode bytes.
~~~~~
This method takes the bytes from a public property that was set by [FindAbsOpcode] and
adds those into the array of bytes.
~~~~~
This method determines if the opcode needs a ModRM byte, if so, finds it. Then
determines if it needs an SIB byte, and if so, finds it.
~~~~~
This determines the displacement type (8 bit, 16 bit, or 32 bit).
~~~~~
This is used when converting the ModRM bytes from binary to hexadecimal; the two bytes
are split up into three pieces of binary, and at the end, they are put together (not
into eachother, but the 3 pieces are put together for the ModRM, and the 3 pieces are
put together for the SIB), and turned into hexadecimal for use as a byte.
~~~~~
This finds the 0, 1, 2, or 4 bytes for Displacement and adds them to the aob.
~~~~~
As with the Displacement, this finds the 0, 1, 2, or 4 bytes for Immediate, and adds
them to the aob.
~~~~~
I'd put the code here, but it's 1888 lines (according to VS), so I've hosted it in a
rar file, that can be found at the bottom, along with the other class.
~~~~~
Functions:
None! =D
Enums:
~~~~~
This is for the different types of things that can help define the array of bytes for
the specific opcode
~~~~~
This defines all the different types of parameters that one can have in an opcode.
~~~~~
Code: |
//Opcode.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace Opcode
{
internal class Opcode //I don't want any outsiders accessing this
{
public Opcode(string Mnemonic, byte[] defined, OpcodeInfo OI1, OpcodeInfo OI2,
Param P1, Param P2, Param P3)
{
mnemonic = Mnemonic;
Defined = defined;
oi1 = OI1;
oi2 = OI2;
p1 = P1;
p2 = P2;
p3 = P3;
}
public string mnemonic = "";
public byte[] Defined; //Pre-defined bytes in the opcode
public OpcodeInfo oi1 = OpcodeInfo.none;
public OpcodeInfo oi2 = OpcodeInfo.none;
public Param p1 = Param.none;
public Param p2 = Param.none;
public Param p3 = Param.none;
public enum OpcodeInfo
{
none,
digit0, digit1, digit2, digit3, digit4, digit5, digit6, digit7, // /digit
r, // /r
cb, cw, cd, cp,
ib, iw, id,
rb, rw, rd,
i
}
public enum Param
{
none,
al, ax, eax,
dx,
dig1, dig3,
cr, dr,
rel8,
rel16, rel32,
ptr1616, ptr1632, //ptr 16:16, ptr16:32
r8, r16, r32,
imm8, imm16, imm32,
rm8, rm16, rm32,
m, m8, m16, m32, m64, m80, m128,
m1616, m1632, //m16:16, m16:32
m16n16, m16n32, m32n32, //m16&16, m16&32, m32&32
moffs8, moffs16, moffs32,
sreg,
m32real, m64real, m80real,
m16int, m32int, m64int,
st0, sti, //st(0), st(i)
mm,
mmm32, mmm64, mmm128//mm-m32, mm-m64, mm-m128
xmm, xmmm32, xmmm64, xmmm128,
cs,ds,es,fs,gs,ss,
cl
}
}
internal static class Opcodes
{
#region AHHH NASTY!! SHIELD YOUR EYES!! >=O
//Super Todo : put 0x66 in all of the byte[]'s for opcodes that have 16-bit
operands (imm16, for example)
public static List<Opcode> ASSEMBLYLANGUAGE = new List<Opcode>(new Opcode[] {
//This uses the IEnumerable overload for creating a new list, by
//creating an array to put in; I like lists a lot more than arrays, though
it's quite hard to directly initialize a list, it's easier to
//initialize it indirectly like this
new Opcode("AAA", new byte[] { 0x37 }, Opcode.OpcodeInfo.none,
Opcode.OpcodeInfo.none, Opcode.Param.none, Opcode.Param.none, Opcode.Param.none),
new Opcode("AAD", new byte[] { 0xD5, 0x0A }, Opcode.OpcodeInfo.none,
Opcode.OpcodeInfo.none, Opcode.Param.none, Opcode.Param.none, Opcode.Param.none),
new Opcode("AAD", new byte[] { 0xD5 }, Opcode.OpcodeInfo.ib,
Opcode.OpcodeInfo.none, Opcode.Param.imm8, Opcode.Param.none, Opcode.Param.none),
new Opcode("AAM", new byte[] { 0xD4, 0x0A }, Opcode.OpcodeInfo.none,
Opcode.OpcodeInfo.none, Opcode.Param.none, Opcode.Param.none, Opcode.Param.none),
new Opcode("AAM", new byte[] { 0xD4 }, Opcode.OpcodeInfo.ib,
Opcode.OpcodeInfo.none, Opcode.Param.imm8, Opcode.Param.none, Opcode.Param.none),
new Opcode("AAS", new byte[] { 0x3F }, Opcode.OpcodeInfo.none,
Opcode.OpcodeInfo.none, Opcode.Param.none, Opcode.Param.none, Opcode.Param.none),
new Opcode("ADC", new byte[] { 0x14 }, Opcode.OpcodeInfo.ib,
Opcode.OpcodeInfo.none, Opcode.Param.al, Opcode.Param.imm8, Opcode.Param.none),
//...
//...
//And here is where I shield your eyes from the rest of the 1000 opcodes. It's
disgusting, believe me.
//I gave you some samples, though, so be happy. =)
#endregion
}
}
|
~~~~~
Credits
Dark Byte
For helping me out with where to get the information (Intel Reference Manual), for
creating Cheat Engine, whose source helped me out, and finally for simply answering all
my questions. Also for having all the opcodes typed out so that I could just use a
translator from Delphi to C# (I created it), so I didn't have to type out ALL the
opcodes (I still typed out some, so I could get a feel of what needed to be done).
Intel
For creating the manual for this, and for creating computers.
Appalsap
for giving me an easy to understand formula for calculating the byte[] for rel32
calls/jmps. =)
ME
For putting so many long hard hours into this.
THANK YOU ALL!!!
~~~~~
Download Links:
Compiled DLL
DLL Source Code
Sample Application (The script converter--also, the opcodes that use relative addresses won't work on here, because I didn't really feel like putting in something to handle them, though I may edit the program and post it back)
Sample Application source
_________________
|
|