Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

.NET Core and .NET Framework binding for the Capstone Disassembly Framework

License

NotificationsYou must be signed in to change notification settings

9ee1/Capstone.NET

Repository files navigation

Capstone.NET is an opinionated .NET Core and a .NET Framework binding for theCapstone disassembly framework. It is written in C#, supportsCapstone 4, and has a friendly and simple type safe API that is ridiculously easy to learn and quick to pick up.

Nuget

Features

  • SupportsCapstone 4. Only the ARM, ARM64, M68K, MIPS, PowerPC, X86, and XCore architectures are supported right now

  • Supports.NET 5 and greater, and.NET Framework 4.6.1 and greater

  • A friendly and simple to use type safe API that is ridiculously easy to learn and pick up

Installation

Either open the NuGet Package Manager in Visual Studio and search for "Capstone.NET" or head over to theNuGet website and download the NuGet package yourself. The NuGet package bundles Capstone. You can also clone this repository and build Capstone.NET yourself.

Building

You can build Capstone.NET by opening the Visual Studio solution inVisual Studio 2017 or greater, and building from there. The Visual Studio solution has "Debug" and "Release" configurations. Make sure you select the configuration you're targeting before you build.

Acknowledgments

Greetings to my sensi Mohamed Saher (@halsten) who suggested I take on this project and was a major help in debugging some stucture alignment issues, the Capstone team (@capstone_engine) for all the great work they are doing, and Matt Graeber (@mattifestation) who wrote the original binding forCapstone 2 and whose work was a starting point for this project.

Short Example

usingGee.External.Capstone;usingGee.External.Capstone.Arm64;namespaceExample{/// <summary>///     Example Program./// </summary>internalstaticclassProgram{/// <summary>///     Run Program./// </summary>/// <param name="args">///     An array of arguments passed from the command line./// </param>internalstaticvoidMain(string[]args){// ...//// Creating the disassembler in a "using" statement ensures that resources get cleaned up automatically// when it is no longer needed.constArm64DisassembleModedisassembleMode=Arm64DisassembleMode.Arm;using(CapstoneArm64Disassemblerdisassembler=CapstoneDisassembler.CreateArm64Disassembler(disassembleMode)){// ....//// Enables disassemble details, which are disabled by default, to provide more detailed information on// disassembled binary code.disassembler.EnableInstructionDetails=true;disassembler.DisassembleSyntax=DisassembleSyntax.Intel;varbinaryCode=newbyte[]{0x09,0x00,0x38,0xd5,0xbf,0x40,0x00,0xd5,0x0c,0x05,0x13,0xd5,0x20,0x50,0x02,0x0e,0x20,0xe4,0x3d,0x0f,0x00,0x18,0xa0,0x5f,0xa2,0x00,0xae,0x9e,0x9f,0x37,0x03,0xd5,0xbf,0x33,0x03,0xd5,0xdf,0x3f,0x03,0xd5,0x21,0x7c,0x02,0x9b,0x21,0x7c,0x00,0x53,0x00,0x40,0x21,0x4b,0xe1,0x0b,0x40,0xb9,0x20,0x04,0x81,0xda,0x20,0x08,0x02,0x8b,0x10,0x5b,0xe8,0x3c};Arm64Instruction[]instructions=disassembler.Disassemble(binaryCode);foreach(Arm64Instructioninstructionininstructions){// ...//// Do your magic!}}}}}

Complete Example

usingGee.External.Capstone;usingGee.External.Capstone.Arm64;usingSystem;namespaceExample{/// <summary>///     Example Program./// </summary>internalstaticclassProgram{/// <summary>///     Run Program./// </summary>/// <param name="args">///     An array of arguments passed from the command line./// </param>internalstaticvoidMain(string[]args){// ...//// Creating the disassembler in a "using" statement ensures that resources get cleaned up automatically// when it is no longer needed.constArm64DisassembleModedisassembleMode=Arm64DisassembleMode.Arm;using(CapstoneArm64Disassemblerdisassembler=CapstoneDisassembler.CreateArm64Disassembler(disassembleMode)){// ....//// Enables disassemble details, which are disabled by default, to provide more detailed information on// disassembled binary code.disassembler.EnableInstructionDetails=true;disassembler.DisassembleSyntax=DisassembleSyntax.Intel;varbinaryCode=newbyte[]{0x09,0x00,0x38,0xd5,0xbf,0x40,0x00,0xd5,0x0c,0x05,0x13,0xd5,0x20,0x50,0x02,0x0e,0x20,0xe4,0x3d,0x0f,0x00,0x18,0xa0,0x5f,0xa2,0x00,0xae,0x9e,0x9f,0x37,0x03,0xd5,0xbf,0x33,0x03,0xd5,0xdf,0x3f,0x03,0xd5,0x21,0x7c,0x02,0x9b,0x21,0x7c,0x00,0x53,0x00,0x40,0x21,0x4b,0xe1,0x0b,0x40,0xb9,0x20,0x04,0x81,0xda,0x20,0x08,0x02,0x8b,0x10,0x5b,0xe8,0x3c};varhexCode=BitConverter.ToString(binaryCode).Replace("-"," ");Console.WriteLine(hexCode);Console.WriteLine();Arm64Instruction[]instructions=disassembler.Disassemble(binaryCode);foreach(Arm64Instructioninstructionininstructions){varaddress=instruction.Address;Arm64InstructionIdid=instruction.Id;if(!instruction.IsDietModeEnabled){// ...//// An instruction's mnemonic and operand text are only available when Diet Mode is disabled.// An exception is thrown otherwise!varmnemonic=instruction.Mnemonic;varoperand=instruction.Operand;Console.WriteLine("{0:X}:\t {1}\t {2}",address,mnemonic,operand);Console.WriteLine("\t Instruction Id = {0}",id);}else{Console.WriteLine("{0:X}:",address);Console.WriteLine("\t Id = {0}",id);}hexCode=BitConverter.ToString(instruction.Bytes).Replace("-"," ");Console.WriteLine("\t Machine Bytes = {0}",hexCode);if(instruction.HasDetails){Console.WriteLine("\t Condition Code = {0}",instruction.Details.ConditionCode);Console.WriteLine("\t Update Flags? = {0}",instruction.Details.UpdateFlags);Console.WriteLine("\t Write Back? = {0}",instruction.Details.WriteBack);if(!instruction.IsDietModeEnabled){// ...//// Instruction groups are only available when Diet Mode is disabled. An exception is// thrown otherwise!Arm64InstructionGroup[]instructionGroups=instruction.Details.Groups;Console.WriteLine("\t # of Instruction Groups: {0}",instructionGroups.Length);for(vari=0;i<instructionGroups.Length;i++){// ...//// A instruction group's name is only available when Diet Mode is disabled. An// exception is thrown otherwise! But since we already checked that it is disabled, we// don't need to perform another check.Arm64InstructionGroupinstructionGroup=instructionGroups[i];Console.Write("\t\t {0}) ",i+1);Console.WriteLine("Id = {0}, Name = {1}",instructionGroup.Id,instructionGroup.Name);}// ...//// Explicitly read registers are only available when Diet Mode is disabled. An exception// is thrown otherwise!Arm64Register[]registers=instruction.Details.ExplicitlyReadRegisters;Console.WriteLine("\t # of Explicitly Read Registers: {0}",registers.Length);for(vari=0;i<registers.Length;i++){// ...//// A register's name is only available when Diet Mode is disabled. An exception is// thrown otherwise! But since we already checked that it is disabled, we don't need// to perform another check.Arm64Registerregister=registers[i];Console.Write("\t\t {0}) ",i+1);Console.WriteLine("Id = {0}, Name = {1}",register.Id,register.Name);}// ...//// Explicitly modified registers are only available when Diet Mode is disabled. An// exception is thrown otherwise!registers=instruction.Details.ExplicitlyWrittenRegisters;Console.WriteLine("\t # of Explicitly Modified Registers: {0}",registers.Length);for(vari=0;i<registers.Length;i++){Arm64Registerregister=registers[i];Console.Write("\t\t {0}) ",i+1);Console.WriteLine("Id = {0}, Name = {1}",register.Id,register.Name);}// ...//// Implicitly read registers are only available when Diet Mode is disabled. An exception// is thrown otherwise!registers=instruction.Details.ImplicitlyReadRegisters;Console.WriteLine("\t # of Implicitly Read Registers: {0}",registers.Length);for(vari=0;i<registers.Length;i++){Arm64Registerregister=registers[i];Console.Write("\t\t {0}) ",i+1);Console.WriteLine("Id = {0}, Name = {1}",register.Id,register.Name);}// ...//// Implicitly modified registers are only available when Diet Mode is disabled. An// exception is thrown otherwise!registers=instruction.Details.ImplicitlyWrittenRegisters;Console.WriteLine("\t # of Implicitly Modified Registers: {0}",registers.Length);for(vari=0;i<registers.Length;i++){Arm64Registerregister=registers[i];Console.Write("\t\t {0}) ",i+1);Console.WriteLine("Id = {0}, Name = {1}",register.Id,register.Name);}}// ...//// An Instruction's operands are always available.Arm64Operand[]operands=instruction.Details.Operands;Console.WriteLine("\t # of Operands: {0}",operands.Length);for(vari=0;i<operands.Length;i++){// ...//// Always check the operand's type before retrieving the associated property. An exception// is thrown otherwise!Arm64Operandoperand=operands[i];Arm64OperandTypeoperandType=operand.Type;Console.WriteLine("\t\t {0}) Operand Type: {1}",i+1,operandType);if(operand.Type==Arm64OperandType.AtOperation){Arm64AtOperationatOperation=operand.AtOperation;Console.WriteLine("\t\t\t Address Translation (AT) Operation = {0}",atOperation);}elseif(operand.Type==Arm64OperandType.BarrierOperation){Arm64BarrierOperationbarrierOperation=operand.BarrierOperation;Console.WriteLine("\t\t\t Barrier Operation = {0}",barrierOperation);}elseif(operand.Type==Arm64OperandType.DcOperation){Arm64DcOperationdcOperation=operand.DcOperation;Console.WriteLine("\t\t\t Data Cache (DC) Operation = {0}",dcOperation);}elseif(operand.Type==Arm64OperandType.FloatingPoint){varfloatingPoint=operand.FloatingPoint;Console.WriteLine("\t\t\t Floating Point Value = {0}",floatingPoint);}elseif(operand.Type==Arm64OperandType.IcOperation){Arm64IcOperationicOperation=operand.IcOperation;Console.WriteLine("\t\t\t Instruction Cache (IC) Operation = {0}",icOperation);}elseif(operand.Type==Arm64OperandType.Immediate){varimmediate=operand.Immediate;Console.WriteLine("\t\t\t Immediate Value = {0:X}",immediate);}elseif(operand.Type==Arm64OperandType.Memory){Arm64MemoryOperandValuememory=operand.Memory;Console.WriteLine("\t\t\t Memory Value:");// ...//// For a memory operand, an irrelevant base register will be a null reference!Arm64Register@base=memory.Base;if(@base!=null){if(!@base.IsDietModeEnabled){// ...//// A register's name is only available when Diet Mode is disabled. An// exception is thrown otherwise!Arm64RegisterIdbaseId=@base.Id;varbaseName=@base.Name;Console.WriteLine("\t\t\t\t Base: Id = {0}, Name = {1}",baseId,baseName);}else{// ...//// A register's unique identifier is always available.Console.WriteLine("\t\t\t\t Base: Id = {0}",@base.Id);}}vardisplacement=memory.Displacement;Console.WriteLine("\t\t\t\t Displacement Value = {0}",displacement);// ...//// For a memory operand, an irrelevant index register will be a null reference!Arm64Registerindex=memory.Index;if(index!=null){if(!index.IsDietModeEnabled){Arm64RegisterIdindexId=index.Id;varindexName=index.Name;Console.WriteLine("\t\t\t\t Index: Id = {0}, Name = {1}",indexId,indexName);}else{Console.WriteLine("\t\t\t\t Index: Id = {0}",index.Id);}}}elseif(operand.Type==Arm64OperandType.MrsSystemRegister){Arm64MrsSystemRegistermrsRegister=operand.MrsSystemRegister;Console.WriteLine("\t\t\t MRS System Register = {0}",mrsRegister);}elseif(operand.Type==Arm64OperandType.MsrSystemRegister){Arm64MsrSystemRegistermsrRegister=operand.MsrSystemRegister;Console.WriteLine("\t\t\t MSR System Register = {0}",msrRegister);}elseif(operand.Type==Arm64OperandType.PStateField){Arm64PStateFieldpStateField=operand.PStateField;Console.WriteLine("\t\t\t Processor State (PSTATE) Field = {0}",pStateField);}elseif(operand.Type==Arm64OperandType.PrefetchOperation){Arm64PrefetchOperationprefetchOperation=operand.PrefetchOperation;Console.WriteLine("\t\t\t Prefetch Operation = {0}",prefetchOperation);}elseif(operand.Type==Arm64OperandType.Register){Arm64Registerregister=operand.Register;if(!register.IsDietModeEnabled){// ...//// A register's name is only available when Diet Mode is disabled. An exception is// thrown otherwise!Arm64RegisterIdregisterId=register.Id;varname=register.Name;Console.WriteLine("\t\t\t Register: Id = {0}, Name = {1}",registerId,name);}else{// ...//// A register's unique identifier is always available.Console.WriteLine("\t\t\t Register: Id = {0}",register.Id);}}if(!operand.IsDietModeEnabled){// ...//// An operand's access type is only available when Diet Mode is disabled. An exception// is thrown otherwise!OperandAccessTypeaccessType=operand.AccessType;Console.WriteLine("\t\t\t Access Type = {0}",accessType);}Arm64ExtendOperationextendOperation=operand.ExtendOperation;Console.WriteLine("\t\t\t Extend Operation = {0}",extendOperation);Arm64ShiftOperationshiftOperation=operand.ShiftOperation;Console.WriteLine("\t\t\t Shift Operation: {0}",shiftOperation);if(shiftOperation!=Arm64ShiftOperation.Invalid){// ...//// An operand's shift value is only available if the shift operation is not invalid.// An exception is thrown otherwise!varshiftValue=operand.ShiftValue;Console.WriteLine("\t\t\t\t Shift Value = {0}",shiftValue);}Arm64VectorArrangementSpecifiervas=operand.VectorArrangementSpecifier;Console.WriteLine("\t\t\t Vector Arrangement Specifier = {0}",vas);Arm64VectorElementSizeSpecifiervess=operand.VectorElementSizeSpecifier;Console.WriteLine("\t\t\t Vector Element Size Specifier = {0}",vess);varvectorIndex=operand.VectorIndex;Console.WriteLine("\t\t\t Vector Index = {0}",vectorIndex);}}Console.WriteLine();Console.ReadLine();}}}}}

[8]ページ先頭

©2009-2025 Movatter.jp