Fetch the repository succeeded.
unit plugin;
{$MODE Delphi}
interface
uses lclproc,
{$ifdef darwin}
macport, dynlibs,
{$endif}
{$ifdef windows}
windows,
{$endif}
classes, sysutils,LCLIntf,checklst,menus,dialogs,CEFuncProc,
NewKernelHandler, graphics, syncobjs, commonTypeDefs, betterControls;
const CurrentPluginVersion=6;
//todo: Move the type definitions to a different unit
//structures
type TPluginVersion = record
version: dword; //version number of ce plugin it is developed for (compatibility for the future)
pluginname: pchar; //pointer to a 0-terminated string in the dll
end;
type PPluginVersion=^TPluginVersion;
type
TPluginDotNetInitResult=packed record
name: pchar;
GetVersion: pointer;
EnablePlugin: pointer;
DisablePlugin: pointer;
version: dword;
end;
TExportedFunctionsDotNetV1=record
sizeofExportedFunctions: integer;
GetLuaState: pointer; //rest is kinda obsolete with lua, e.g hooking happens with AA scripts in the local CE
LuaRegister: pointer;
LuaPushClassInstance: pointer;
ProcessMessages: pointer; //in case it's a messy plugin that wants to run in the main thread
CheckSynchronize: pointer;
end;
TExportedFunctions5 = record
sizeofExportedFunctions: integer;
showmessage: pointer;
registerfunction: pointer;
unregisterfunction: pointer;
OpenedProcessID: ^dword;
OpenedProcessHandle: ^thandle;
GetMainWindowHandle: pointer;
AutoAssemble: pointer;
assembler: pointer;
disassembler: pointer;
ChangeRegistersAtAddress: pointer;
InjectDLL: pointer;
freezemem: pointer;
unfreezemem: pointer;
fixmem: pointer;
processlist: pointer;
reloadsettings: pointer;
getaddressfrompointer: pointer;
//pointers to the address that contains the pointers to the functions
ReadProcessMemory :pointer;
WriteProcessMemory :pointer;
GetThreadContext :pointer;
SetThreadContext :pointer;
SuspendThread :pointer;
ResumeThread :pointer;
OpenProcess :pointer;
WaitForDebugEvent :pointer;
ContinueDebugEvent :pointer;
DebugActiveProcess :pointer;
StopDebugging :pointer;
StopRegisterChange :pointer;
VirtualProtect :pointer;
VirtualProtectEx :pointer;
VirtualQueryEx :pointer;
VirtualAllocEx :pointer;
CreateRemoteThread :pointer;
OpenThread :pointer;
GetPEProcess :pointer;
GetPEThread :pointer;
GetThreadsProcessOffset:pointer;
GetThreadListEntryOffset:pointer;
GetProcessnameOffset :pointer;
GetDebugportOffset :pointer;
GetPhysicalAddress :pointer;
ProtectMe :pointer;
GetCR4 :pointer;
GetCR3 :pointer;
SetCR3 :pointer;
GetSDT :pointer;
GetSDTShadow :pointer;
setAlternateDebugMethod: pointer;
getAlternateDebugMethod: pointer;
DebugProcess :pointer;
ChangeRegOnBP :pointer;
RetrieveDebugData :pointer;
StartProcessWatch :pointer;
WaitForProcessListData:pointer;
GetProcessNameFromID :pointer;
GetProcessNameFromPEProcess:pointer;
KernelOpenProcess :pointer;
KernelReadProcessMemory :pointer;
KernelWriteProcessMemory:pointer;
KernelVirtualAllocEx :pointer;
IsValidHandle :pointer;
GetIDTCurrentThread :pointer;
GetIDTs :pointer;
MakeWritable :pointer;
GetLoadedState :pointer;
DBKSuspendThread :pointer;
DBKResumeThread :pointer;
DBKSuspendProcess :pointer;
DBKResumeProcess :pointer;
KernelAlloc :pointer;
GetKProcAddress :pointer;
CreateToolhelp32Snapshot:pointer;
Process32First :pointer;
Process32Next :pointer;
Thread32First :pointer;
Thread32Next :pointer;
Module32First :pointer;
Module32Next :pointer;
Heap32ListFirst :pointer;
Heap32ListNext :pointer;
//advanced for delphi 7 enterprise dll programmers only
mainform :pointer;
memorybrowser :pointer;
//version 2 extension:
sym_nameToAddress : pointer;
sym_addressToName : pointer;
sym_generateAPIHookScript : pointer;
//version 3 extension
loadDBK32 : pointer;
loaddbvmifneeded : pointer;
previousOpcode : pointer;
nextOpcode : pointer;
disassembleEx : pointer;
loadModule : pointer;
aa_AddExtraCommand: pointer;
aa_RemoveExtraCommand: pointer;
//version 4 extension
createTableEntry: pointer;
getTableEntry: pointer;
memrec_setDescription: pointer;
memrec_getDescription: pointer ;
memrec_getAddress: pointer;
memrec_setAddress: pointer;
memrec_getType: pointer;
memrec_setType: pointer;
memrec_getValue: pointer;
memrec_setValue: pointer;
memrec_getScript: pointer;
memrec_setScript: pointer;
memrec_isfrozen: pointer;
memrec_freeze: pointer;
memrec_unfreeze: pointer;
memrec_setColor: pointer;
memrec_appendtoentry: pointer;
memrec_delete: pointer;
getProcessIDFromProcessName: pointer;
openProcessEx: pointer;
debugProcessEx: pointer;
pause: pointer;
unpause: pointer;
debug_setBreakpoint: pointer;
debug_removeBreakpoint: pointer;
debug_continueFromBreakpoint: pointer;
closeCE: pointer;
hideAllCEWindows: pointer;
unhideMainCEwindow: pointer;
createForm: pointer;
form_centerScreen: pointer;
form_hide: pointer;
form_show: pointer;
form_onClose: pointer;
createPanel: pointer;
createGroupBox: pointer;
createButton: pointer;
createImage: pointer;
image_loadImageFromFile: pointer;
image_transparent: pointer;
image_stretch: pointer;
createLabel: pointer;
createEdit: pointer;
createMemo: pointer;
createTimer: pointer;
timer_setInterval: pointer;
timer_onTimer: pointer;
control_setCaption: pointer;
control_getCaption: pointer;
control_setPosition: pointer;
control_getX: pointer;
control_getY: pointer;
control_setSize: pointer;
control_getWidth: pointer;
control_getHeight: pointer;
control_setAlign: pointer;
control_onClick: pointer;
object_destroy: pointer;
messageDialog: pointer;
speedhack_setSpeed: pointer;
//version 5
ExecuteKernelCode: pointer;
UserdefinedInterruptHook: pointer;
GetLuaState: pointer;
MainThreadCall: pointer;
end;
type PExportedFunctions5 = ^TExportedFunctions5;
type TExportedFunctions = TExportedFunctions5; //<----adjust on new version
type TExportedFunctions4 = record
sizeofExportedFunctions: integer;
showmessage: pointer;
registerfunction: pointer;
unregisterfunction: pointer;
OpenedProcessID: ^dword;
OpenedProcessHandle: ^thandle;
GetMainWindowHandle: pointer;
AutoAssemble: pointer;
assembler: pointer;
disassembler: pointer;
ChangeRegistersAtAddress: pointer;
InjectDLL: pointer;
freezemem: pointer;
unfreezemem: pointer;
fixmem: pointer;
processlist: pointer;
reloadsettings: pointer;
getaddressfrompointer: pointer;
//pointers to the address that contains the pointers to the functions
ReadProcessMemory :pointer;
WriteProcessMemory :pointer;
GetThreadContext :pointer;
SetThreadContext :pointer;
SuspendThread :pointer;
ResumeThread :pointer;
OpenProcess :pointer;
WaitForDebugEvent :pointer;
ContinueDebugEvent :pointer;
DebugActiveProcess :pointer;
StopDebugging :pointer;
StopRegisterChange :pointer;
VirtualProtect :pointer;
VirtualProtectEx :pointer;
VirtualQueryEx :pointer;
VirtualAllocEx :pointer;
CreateRemoteThread :pointer;
OpenThread :pointer;
GetPEProcess :pointer;
GetPEThread :pointer;
GetThreadsProcessOffset:pointer;
GetThreadListEntryOffset:pointer;
GetProcessnameOffset :pointer;
GetDebugportOffset :pointer;
GetPhysicalAddress :pointer;
ProtectMe :pointer;
GetCR4 :pointer;
GetCR3 :pointer;
SetCR3 :pointer;
GetSDT :pointer;
GetSDTShadow :pointer;
setAlternateDebugMethod: pointer;
getAlternateDebugMethod: pointer;
DebugProcess :pointer;
ChangeRegOnBP :pointer;
RetrieveDebugData :pointer;
StartProcessWatch :pointer;
WaitForProcessListData:pointer;
GetProcessNameFromID :pointer;
GetProcessNameFromPEProcess:pointer;
KernelOpenProcess :pointer;
KernelReadProcessMemory :pointer;
KernelWriteProcessMemory:pointer;
KernelVirtualAllocEx :pointer;
IsValidHandle :pointer;
GetIDTCurrentThread :pointer;
GetIDTs :pointer;
MakeWritable :pointer;
GetLoadedState :pointer;
DBKSuspendThread :pointer;
DBKResumeThread :pointer;
DBKSuspendProcess :pointer;
DBKResumeProcess :pointer;
KernelAlloc :pointer;
GetKProcAddress :pointer;
CreateToolhelp32Snapshot:pointer;
Process32First :pointer;
Process32Next :pointer;
Thread32First :pointer;
Thread32Next :pointer;
Module32First :pointer;
Module32Next :pointer;
Heap32ListFirst :pointer;
Heap32ListNext :pointer;
//advanced for delphi 7 enterprise dll programmers only
mainform :pointer;
memorybrowser :pointer;
//version 2 extension:
sym_nameToAddress : pointer;
sym_addressToName : pointer;
sym_generateAPIHookScript : pointer;
//version 3 extension
loadDBK32 : pointer;
loaddbvmifneeded : pointer;
previousOpcode : pointer;
nextOpcode : pointer;
disassembleEx : pointer;
loadModule : pointer;
aa_AddExtraCommand: pointer;
aa_RemoveExtraCommand: pointer;
//version 4 extension
createTableEntry: pointer;
getTableEntry: pointer;
memrec_setDescription: pointer;
memrec_getDescription: pointer ;
memrec_getAddress: pointer;
memrec_setAddress: pointer;
memrec_getType: pointer;
memrec_setType: pointer;
memrec_getValue: pointer;
memrec_setValue: pointer;
memrec_getScript: pointer;
memrec_setScript: pointer;
memrec_isfrozen: pointer;
memrec_freeze: pointer;
memrec_unfreeze: pointer;
memrec_setColor: pointer;
memrec_appendtoentry: pointer;
memrec_delete: pointer;
getProcessIDFromProcessName: pointer;
openProcessEx: pointer;
debugProcessEx: pointer;
pause: pointer;
unpause: pointer;
debug_setBreakpoint: pointer;
debug_removeBreakpoint: pointer;
debug_continueFromBreakpoint: pointer;
closeCE: pointer;
hideAllCEWindows: pointer;
unhideMainCEwindow: pointer;
createForm: pointer;
form_centerScreen: pointer;
form_hide: pointer;
form_show: pointer;
form_onClose: pointer;
createPanel: pointer;
createGroupBox: pointer;
createButton: pointer;
createImage: pointer;
image_loadImageFromFile: pointer;
image_transparent: pointer;
image_stretch: pointer;
createLabel: pointer;
createEdit: pointer;
createMemo: pointer;
createTimer: pointer;
timer_setInterval: pointer;
timer_onTimer: pointer;
control_setCaption: pointer;
control_getCaption: pointer;
control_setPosition: pointer;
control_getX: pointer;
control_getY: pointer;
control_setSize: pointer;
control_getWidth: pointer;
control_getHeight: pointer;
control_setAlign: pointer;
control_onClick: pointer;
object_destroy: pointer;
messageDialog: pointer;
speedhack_setSpeed: pointer;
end;
type PExportedFunctions4 = ^TExportedFunctions4;
type TExportedFunctions3 = record
sizeofExportedFunctions: integer;
showmessage: pointer;
registerfunction: pointer;
unregisterfunction: pointer;
OpenedProcessID: ^dword;
OpenedProcessHandle: ^thandle;
GetMainWindowHandle: pointer;
AutoAssemble: pointer;
assembler: pointer;
disassembler: pointer;
ChangeRegistersAtAddress: pointer;
InjectDLL: pointer;
freezemem: pointer;
unfreezemem: pointer;
fixmem: pointer;
processlist: pointer;
reloadsettings: pointer;
getaddressfrompointer: pointer;
//pointers to the address that contains the pointers to the functions
ReadProcessMemory :pointer;
WriteProcessMemory :pointer;
GetThreadContext :pointer;
SetThreadContext :pointer;
SuspendThread :pointer;
ResumeThread :pointer;
OpenProcess :pointer;
WaitForDebugEvent :pointer;
ContinueDebugEvent :pointer;
DebugActiveProcess :pointer;
StopDebugging :pointer;
StopRegisterChange :pointer;
VirtualProtect :pointer;
VirtualProtectEx :pointer;
VirtualQueryEx :pointer;
VirtualAllocEx :pointer;
CreateRemoteThread :pointer;
OpenThread :pointer;
GetPEProcess :pointer;
GetPEThread :pointer;
GetThreadsProcessOffset:pointer;
GetThreadListEntryOffset:pointer;
GetProcessnameOffset :pointer;
GetDebugportOffset :pointer;
GetPhysicalAddress :pointer;
ProtectMe :pointer;
GetCR4 :pointer;
GetCR3 :pointer;
SetCR3 :pointer;
GetSDT :pointer;
GetSDTShadow :pointer;
setAlternateDebugMethod: pointer;
getAlternateDebugMethod: pointer;
DebugProcess :pointer;
ChangeRegOnBP :pointer;
RetrieveDebugData :pointer;
StartProcessWatch :pointer;
WaitForProcessListData:pointer;
GetProcessNameFromID :pointer;
GetProcessNameFromPEProcess:pointer;
KernelOpenProcess :pointer;
KernelReadProcessMemory :pointer;
KernelWriteProcessMemory:pointer;
KernelVirtualAllocEx :pointer;
IsValidHandle :pointer;
GetIDTCurrentThread :pointer;
GetIDTs :pointer;
MakeWritable :pointer;
GetLoadedState :pointer;
DBKSuspendThread :pointer;
DBKResumeThread :pointer;
DBKSuspendProcess :pointer;
DBKResumeProcess :pointer;
KernelAlloc :pointer;
GetKProcAddress :pointer;
CreateToolhelp32Snapshot:pointer;
Process32First :pointer;
Process32Next :pointer;
Thread32First :pointer;
Thread32Next :pointer;
Module32First :pointer;
Module32Next :pointer;
Heap32ListFirst :pointer;
Heap32ListNext :pointer;
//advanced for delphi 7 enterprise dll programmers only
mainform :pointer;
memorybrowser :pointer;
//version 2 extension:
sym_nameToAddress : pointer;
sym_addressToName : pointer;
sym_generateAPIHookScript : pointer;
//version 3 extension
loadDBK32 : pointer;
loaddbvmifneeded : pointer;
previousOpcode : pointer;
nextOpcode : pointer;
disassembleEx : pointer;
loadModule : pointer;
aa_AddExtraCommand: pointer;
aa_RemoveExtraCommand: pointer;
end;
type PExportedFunctions3 = ^TExportedFunctions3;
type TExportedFunctions2 = record
sizeofExportedFunctions: integer;
showmessage: pointer;
registerfunction: pointer;
unregisterfunction: pointer;
OpenedProcessID: ^dword;
OpenedProcessHandle: ^thandle;
GetMainWindowHandle: pointer;
AutoAssemble: pointer;
assembler: pointer;
disassembler: pointer;
ChangeRegistersAtAddress: pointer;
InjectDLL: pointer;
freezemem: pointer;
unfreezemem: pointer;
fixmem: pointer;
processlist: pointer;
reloadsettings: pointer;
getaddressfrompointer: pointer;
//pointers to the address that contains the pointers to the functions
ReadProcessMemory :pointer;
WriteProcessMemory :pointer;
GetThreadContext :pointer;
SetThreadContext :pointer;
SuspendThread :pointer;
ResumeThread :pointer;
OpenProcess :pointer;
WaitForDebugEvent :pointer;
ContinueDebugEvent :pointer;
DebugActiveProcess :pointer;
StopDebugging :pointer;
StopRegisterChange :pointer;
VirtualProtect :pointer;
VirtualProtectEx :pointer;
VirtualQueryEx :pointer;
VirtualAllocEx :pointer;
CreateRemoteThread :pointer;
OpenThread :pointer;
GetPEProcess :pointer;
GetPEThread :pointer;
GetThreadsProcessOffset:pointer;
GetThreadListEntryOffset:pointer;
GetProcessnameOffset :pointer;
GetDebugportOffset :pointer;
GetPhysicalAddress :pointer;
ProtectMe :pointer;
GetCR4 :pointer;
GetCR3 :pointer;
SetCR3 :pointer;
GetSDT :pointer;
GetSDTShadow :pointer;
setAlternateDebugMethod: pointer;
getAlternateDebugMethod: pointer;
DebugProcess :pointer;
ChangeRegOnBP :pointer;
RetrieveDebugData :pointer;
StartProcessWatch :pointer;
WaitForProcessListData:pointer;
GetProcessNameFromID :pointer;
GetProcessNameFromPEProcess:pointer;
KernelOpenProcess :pointer;
KernelReadProcessMemory :pointer;
KernelWriteProcessMemory:pointer;
KernelVirtualAllocEx :pointer;
IsValidHandle :pointer;
GetIDTCurrentThread :pointer;
GetIDTs :pointer;
MakeWritable :pointer;
GetLoadedState :pointer;
DBKSuspendThread :pointer;
DBKResumeThread :pointer;
DBKSuspendProcess :pointer;
DBKResumeProcess :pointer;
KernelAlloc :pointer;
GetKProcAddress :pointer;
CreateToolhelp32Snapshot:pointer;
Process32First :pointer;
Process32Next :pointer;
Thread32First :pointer;
Thread32Next :pointer;
Module32First :pointer;
Module32Next :pointer;
Heap32ListFirst :pointer;
Heap32ListNext :pointer;
//advanced for delphi 7 enterprise dll programmers only
mainform :pointer;
memorybrowser :pointer;
//version 2 extension:
sym_nameToAddress : pointer;
sym_addressToName : pointer;
sym_generateAPIHookScript : pointer;
end;
type PExportedFunctions2 = ^TExportedFunctions2;
type TExportedFunctions1 = record
sizeofExportedFunctions: integer;
showmessage: pointer;
registerfunction: pointer;
unregisterfunction: pointer;
OpenedProcessID: ^dword;
OpenedProcessHandle: ^thandle;
GetMainWindowHandle: pointer;
AutoAssemble: pointer;
assembler: pointer;
disassembler: pointer;
ChangeRegistersAtAddress: pointer;
InjectDLL: pointer;
freezemem: pointer;
unfreezemem: pointer;
fixmem: pointer;
processlist: pointer;
reloadsettings: pointer;
getaddressfrompointer: pointer;
//pointers to the address that contains the pointers to the functions
ReadProcessMemory :pointer;
WriteProcessMemory :pointer;
GetThreadContext :pointer;
SetThreadContext :pointer;
SuspendThread :pointer;
ResumeThread :pointer;
OpenProcess :pointer;
WaitForDebugEvent :pointer;
ContinueDebugEvent :pointer;
DebugActiveProcess :pointer;
StopDebugging :pointer;
StopRegisterChange :pointer;
VirtualProtect :pointer;
VirtualProtectEx :pointer;
VirtualQueryEx :pointer;
VirtualAllocEx :pointer;
CreateRemoteThread :pointer;
OpenThread :pointer;
GetPEProcess :pointer;
GetPEThread :pointer;
GetThreadsProcessOffset:pointer;
GetThreadListEntryOffset:pointer;
GetProcessnameOffset :pointer;
GetDebugportOffset :pointer;
GetPhysicalAddress :pointer;
ProtectMe :pointer;
GetCR4 :pointer;
GetCR3 :pointer;
SetCR3 :pointer;
GetSDT :pointer;
GetSDTShadow :pointer;
setAlternateDebugMethod: pointer;
getAlternateDebugMethod: pointer;
DebugProcess :pointer;
ChangeRegOnBP :pointer;
RetrieveDebugData :pointer;
StartProcessWatch :pointer;
WaitForProcessListData:pointer;
GetProcessNameFromID :pointer;
GetProcessNameFromPEProcess:pointer;
KernelOpenProcess :pointer;
KernelReadProcessMemory :pointer;
KernelWriteProcessMemory:pointer;
KernelVirtualAllocEx :pointer;
IsValidHandle :pointer;
GetIDTCurrentThread :pointer;
GetIDTs :pointer;
MakeWritable :pointer;
GetLoadedState :pointer;
DBKSuspendThread :pointer;
DBKResumeThread :pointer;
DBKSuspendProcess :pointer;
DBKResumeProcess :pointer;
KernelAlloc :pointer;
GetKProcAddress :pointer;
CreateToolhelp32Snapshot:pointer;
Process32First :pointer;
Process32Next :pointer;
Thread32First :pointer;
Thread32Next :pointer;
Module32First :pointer;
Module32Next :pointer;
Heap32ListFirst :pointer;
Heap32ListNext :pointer;
//advanced for delphi 7 enterprise dll programmers only
mainform :pointer;
memorybrowser :pointer;
previousOpcode :pointer;
end;
type PExportedFunctions1 = ^TExportedFunctions1;
type PExportedFunctions = ^TExportedFunctions; //same
//exported functions of the plugin
type TGetVersion=function(var PluginVersion:TPluginVersion; TPluginVersionSize: integer):BOOL; stdcall;
type TInitializePlugin=function(var ExportedFunctions: TExportedFunctions; pluginid: dword):BOOL; stdcall;
type TDisablePlugin=function:BOOL; stdcall;
//plugin type 0:
//where: rightclick on the address list in the menu plugin, user activated
type TPlugin0_SelectedRecord=record
interpretedaddress: pchar; //pointer to a 255 bytes long string (0 terminated)
address: ptrUint; //this is a read-only representaion of the address. Change interpretedaddress if you want to change this
ispointer: BOOL; //readonly
countoffsets: integer; //readonly
offsets: PDWordArray; //pointer to a array of dwords randing from 0 to countoffsets-1 (readonly)
description: pchar; //pointer to a 255 bytes long string
valuetype: byte;
size: byte; //stringlenth or bitlength (max 255);
end;
type PPlugin0_SelectedRecord=^TPlugin0_SelectedRecord;
type TPluginfunction0=function(selectedrecord: PPlugin0_SelectedRecord):bool; stdcall;
//private plugin data
type TPluginfunctionType0=class
public
pluginid: integer;
functionid: integer;
name:string;
callback: TPluginfunction0;
menuitem: TMenuItem;
end;
//plugin type 1:
//where: menu bar under plugins in memory view, user activated
type TPluginfunction1=function(disassembleraddress: pptruint; selected_disassembler_address: pptruint; hexviewaddress:pptruint ):bool; stdcall;
//private plugin data
type TPluginfunctionType1=class
public
pluginid: integer;
functionid: integer;
name:string;
callback: TPluginfunction1;
menuitem: TMenuItem;
end;
//plugin type 2:
//where: when a debug event happens
type TPluginFunction2=function(debugevent: PDebugEvent):integer; stdcall; //return 0 if you want to let ce handle it as well, 1 if you don't want to let ce handle it as well (in case of not handling, do ContinueDebugEvent yourself)
type TPluginfunctionType2=class
public
pluginid: integer;
functionid: integer;
callback: TPluginFunction2;
end;
//plugin type 3:
//where: a new process created according to the processwatcher
type TPluginFunction3=function(processid: dword; peprocess:ptruint; created: BOOL):integer; stdcall;
type TPluginFunction3Version1=function(processid: dword; peprocess:ptruint):integer; stdcall;
type TPluginfunctionType3=class
public
pluginid: integer;
functionid: integer;
callback: TPluginfunction3;
end;
//plugin type 4:
//where: Functionpointerchange notification
type TPluginFunction4=function(section: integer):boolean; stdcall;
type TPluginfunctionType4=class
public
pluginid: integer;
functionid: integer;
callback: TPluginFunction4;
end;
//plugin type 5:
//where: Main form's menu, plugin
type TPluginfunction5=procedure; stdcall;
//private plugin data
type TPluginfunctionType5=class
public
pluginid: integer;
functionid: integer;
name:string;
callback: TPluginfunction5;
menuitem: TMenuItem;
end;
//plugin type 6:
//where: rightclick context of the disassembler
type TPluginfunction6=function(selectedAddress: pptruint):bool; stdcall;
type Tpluginfuntion6OnContext=function(selectedAddress: ptruint; addressofname: pointer; show: pbool):bool; stdcall;
type Tpluginfuntion6OnContextVersion5=function(selectedAddress: ptruint; addressofname: pointer):bool; stdcall;
//private plugin data
type TPluginfunctionType6=class
public
pluginid: integer;
functionid: integer;
name:string;
callback: TPluginfunction6;
callbackOnContext: Tpluginfuntion6OnContext;
menuitem: TMenuItem;
end;
//plugin type 7:
//where: when a disassembler line is being rendered
type TPluginFunction7=procedure(address: ptruint; addressStringPointer: pointer; bytestringpointer: pointer; opcodestringpointer: pointer; specialstringpointer: pointer; textcolor: PColor); stdcall;
type TPluginfunctionType7=class
public
pluginid: integer;
functionid: integer;
callback: TPluginFunction7;
end;
//plugin type 8
//where: when the autoassembler is used in the first and 2nd stage
type TPluginFunction8=procedure(line: ppchar; phase: integer; id: integer); stdcall;
type TPluginFunction8Version5=procedure(line: ppchar; phase: integer); stdcall;
type TPluginfunctionType8=class
public
pluginid: integer;
functionid: integer;
callback: TPluginFunction8;
end;
type TPlugin = record
dllname: string;
filepath: string;
hmodule: thandle;
name: string;
pluginversion: integer;
dotnet: boolean;
enabled: boolean;
GetVersion: TGetVersion;
EnablePlugin: TInitializePlugin;
DisablePlugin: TDisablePlugin;
nextid: integer;
RegisteredFunctions0: array of TPluginfunctionType0;
RegisteredFunctions1: array of TPluginfunctionType1;
RegisteredFunctions2: array of TPluginfunctionType2;
RegisteredFunctions3: array of TPluginfunctionType3;
RegisteredFunctions4: array of TPluginfunctionType4;
RegisteredFunctions5: array of TPluginfunctionType5;
RegisteredFunctions6: array of TPluginfunctionType6;
RegisteredFunctions7: array of TPluginfunctionType7;
RegisteredFunctions8: array of TPluginfunctionType8;
end;
type TPluginHandler=class
private
pluginCS: TCriticalSection;
plugins: array of TPlugin;
function GetDLLFilePath(pluginid: integer):string;
function DotNetPluginGetPluginName(dllname: string): string;
function DotNetLoadPlugin(dllname:string):integer;
public
function GetPluginID(dllname:string):integer;
function GetPluginName(dllname:string):string;
function LoadPlugin(dllname: string):integer;
procedure UnloadPlugin(pluginid: integer);
procedure FillCheckListBox(clb: TCheckListbox);
procedure EnablePlugin(pluginid: integer);
procedure DisablePlugin(pluginid: integer);
procedure handleAutoAssemblerPlugin(line: ppchar; phase: integer; id: integer);
procedure handledisassemblerContextPopup(address: ptruint);
procedure handledisassemblerplugins(address: ptruint; addressStringPointer: pointer; bytestringpointer: pointer; opcodestringpointer: pointer; specialstringpointer: pointer; textcolor: PColor);
function handledebuggerplugins(devent:PDebugEvent):integer;
function handlenewprocessplugins(processid: dword; peprocess:ptruint; created: boolean):boolean;
function handlechangedpointers(section: integer):boolean;
function registerfunction(pluginid,functiontype:integer; init: pointer):integer;
function unregisterfunction(pluginid,functionid: integer): boolean;
property dllfilepath[pluginid: integer]: string read getdllfilepath;
constructor create;
destructor destroy; override;
end;
var pluginhandler: TPluginhandler;
exportedfunctions: TExportedFunctions;
exportedfunctionsdotnet: TExportedFunctionsDotNetV1;
onAPIPointerChange: TNotifyEvent;
implementation
uses MainUnit,memorybrowserformunit,formsettingsunit, pluginexports, SynHighlighterAA,
{$ifdef windows}DBK32functions,{$endif} luahandler, processhandlerunit
{$ifdef windows}, BetterDLLSearchPath{$endif}, dotnethost, PEInfoFunctions, luaclass;
resourcestring
rsErrorEnabling = 'Error enabling %s';
rsErrorDisabling = 'Error disabling %s';
rsErrorLoadingOnlyDLLFilesAreAllowed = 'Error loading %s. Only DLL files are allowed';
rsErrorLoadingTheDllIsMissingTheCEPlugin_GetVersionF = 'Error loading %s. The dll is missing the CEPlugin_GetVersion function';
rsIsMissingTheCEPlugin_InitializePluginExport = '%s is missing the CEPlugin_InitializePlugin export';
rsIsMissingTheCEPlugin_DisablePluginExport = '%s is missing the CEPlugin_DisablePlugin export';
rsErrorLoadingTheDllIsMissingTheCEPlugin_GetVersionE = 'Error loading %s. The dll is missing the CEPlugin_GetVersion export';
rsErrorLoadingThisDllRequiresANewerVersionOfCeToFunc = 'Error loading %s. This dll requires a newer version of ce to function properly';
rsErrorLoadingTheGetVersionFunctionReturnedFALSE = 'Error loading %s. The GetVersion function returned FALSE';
rsPlugThePluginDllCouldNotBeLoaded = 'The plugin dll could not be loaded:';
function TPluginHandler.GetDLLFilePath(pluginid: integer):string;
begin
pluginCS.Enter;
result:=plugins[pluginid].filepath;
pluginCS.Leave;
end;
function TPluginHandler.registerfunction(pluginid,functiontype:integer; init: pointer):integer;
type Tfunction0=record
name: pchar;
callbackroutine: pointer;
end;
type Tfunction1=record
name: pchar;
callbackroutine: pointer;
shortcut: pchar;
end;
type TFunction2=record
callbackroutine: pointer;
end;
type Tfunction6=record
name: pchar;
callbackroutine: pointer;
callbackroutineOnContext: pointer;
shortcut: pchar;
end;
type PFunction0=^TFunction0;
type Pfunction1=^TFunction1; //same
type Pfunction2=^TFunction2;
type PFunction3=^TFunction2;
type PFunction4=^TFunction2;
type PFunction5=^TFunction1;
type PFunction6=^TFunction6;
type PFunction7=^TFunction2;
type PFunction8=^TFunction2;
var i: integer;
newmenuitem: TMenuItem;
f0: TPluginfunctionType0;
f1: TPluginfunctionType1;
f2: TPluginfunctionType2;
f3: TPluginfunctionType3;
f4: TPluginfunctionType4;
f5: TPluginfunctionType5;
f6: TPluginfunctionType6;
f7: TPluginfunctionType7;
f8: TPluginfunctionType8;
begin
result:=-1;
pluginCS.enter;
try
if pluginid>=length(plugins) then exit;
case functiontype of
0: begin
//plugin for the rightclick on the addresslist
f0:=TPluginfunctionType0.Create;
f0.pluginid:=pluginid;
f0.functionid:=plugins[pluginid].nextid;
f0.name:=PFunction0(init).name;
f0.callback:=PFunction0(init).callbackroutine;
if not mainform.Plugins1.Visible then
mainform.Plugins1.Visible:=true;
newmenuitem:=tmenuitem.Create(mainform);
newmenuitem.Caption:=f0.name;
newmenuitem.Tag:=ptruint(f0);
newmenuitem.onclick:=mainform.plugintype0click;
mainform.Plugins1.Add(newmenuitem);
f0.menuitem:=newmenuitem;
setlength(plugins[pluginid].RegisteredFunctions0,length(plugins[pluginid].RegisteredFunctions0)+1);
plugins[pluginid].RegisteredFunctions0[length(plugins[pluginid].RegisteredFunctions0)-1]:=f0;
result:=plugins[pluginid].nextid;
end;
1: begin
//plugin for the memorybrowser
f1:=TPluginfunctionType1.Create;
f1.pluginid:=pluginid;
f1.functionid:=plugins[pluginid].nextid;
f1.name:=Pfunction1(init).name;
f1.callback:=Pfunction1(init).callbackroutine;
if not memorybrowser.Plugins1.Visible then
memorybrowser.Plugins1.Visible:=true;
newmenuitem:=tmenuitem.Create(mainform);
newmenuitem.Caption:=f1.name;
newmenuitem.Tag:=ptruint(f1);
newmenuitem.onclick:=memorybrowser.plugintype1click;
if plugins[pluginid].pluginversion>1 then
begin
try
newmenuitem.ShortCut:=TextToShortCut(PFunction1(init).shortcut);
except
end;
end;
memorybrowser.Plugins1.Add(newmenuitem);
f1.menuitem:=newmenuitem;
setlength(plugins[pluginid].Registeredfunctions1,length(plugins[pluginid].Registeredfunctions1)+1);
plugins[pluginid].Registeredfunctions1[length(plugins[pluginid].Registeredfunctions1)-1]:=f1;
result:=plugins[pluginid].nextid;
end;
2: begin
//debugger for the memorybrowser
f2:=TPluginfunctionType2.Create;
f2.pluginid:=pluginid;
f2.functionid:=plugins[pluginid].nextid;
f2.callback:=Pfunction2(init).callbackroutine;
setlength(plugins[pluginid].RegisteredFunctions2,length(plugins[pluginid].RegisteredFunctions2)+1);
plugins[pluginid].RegisteredFunctions2[length(plugins[pluginid].RegisteredFunctions2)-1]:=f2;
result:=plugins[pluginid].nextid;
end;
3: begin
//process created
f3:=TPluginfunctionType3.Create;
f3.pluginid:=pluginid;
f3.functionid:=plugins[pluginid].nextid;
f3.callback:=Pfunction2(init).callbackroutine;
setlength(plugins[pluginid].Registeredfunctions3, length(plugins[pluginid].Registeredfunctions3)+1);
plugins[pluginid].Registeredfunctions3[length(plugins[pluginid].Registeredfunctions3)-1]:=f3;
result:=plugins[pluginid].nextid;
end;
4: begin
//function pointers changed
f4:=TPluginfunctionType4.Create;
f4.pluginid:=pluginid;
f4.functionid:=plugins[pluginid].nextid;
f4.callback:=Pfunction2(init).callbackroutine;
setlength(plugins[pluginid].RegisteredFunctions4, length(plugins[pluginid].Registeredfunctions4)+1);
plugins[pluginid].Registeredfunctions4[length(plugins[pluginid].Registeredfunctions4)-1]:=f4;
result:=plugins[pluginid].nextid;
end;
5: begin
//main menu
f5:=TPluginfunctionType5.Create;
f5.pluginid:=pluginid;
f5.functionid:=plugins[pluginid].nextid;
f5.name:=Pfunction5(init).name;
f5.callback:=Pfunction5(init).callbackroutine;
if not mainform.Plugins2.Visible then
mainform.Plugins2.Visible:=true;
newmenuitem:=tmenuitem.Create(mainform);
newmenuitem.Caption:=f5.name;
newmenuitem.Tag:=ptruint(f5);
newmenuitem.onclick:=mainform.plugintype5click;
try
newmenuitem.ShortCut:=TextToShortCut(PFunction5(init).shortcut);
except
end;
mainform.Plugins2.Add(newmenuitem);
f5.menuitem:=newmenuitem;
setlength(plugins[pluginid].Registeredfunctions5,length(plugins[pluginid].Registeredfunctions5)+1);
plugins[pluginid].Registeredfunctions5[length(plugins[pluginid].Registeredfunctions5)-1]:=f5;
result:=plugins[pluginid].nextid;
end;
6: begin
//memorybrowser rightclick on disassembler
f6:=TPluginfunctionType6.Create;
f6.pluginid:=pluginid;
f6.functionid:=plugins[pluginid].nextid;
f6.name:=Pfunction6(init).name;
f6.callback:=Pfunction6(init).callbackroutine;
f6.callbackOnContext:=Pfunction6(init).callbackroutineOnContext;
newmenuitem:=tmenuitem.Create(memorybrowser);
newmenuitem.Caption:=f6.name;
newmenuitem.Tag:=ptruint(f6);
newmenuitem.onclick:=memorybrowser.plugintype6click;
memorybrowser.debuggerpopup.Items.Add(newmenuitem);
try
newmenuitem.ShortCut:=TextToShortCut(PFunction6(init).shortcut);
except
end;
f6.menuitem:=newmenuitem;
setlength(plugins[pluginid].Registeredfunctions6,length(plugins[pluginid].Registeredfunctions6)+1);
plugins[pluginid].Registeredfunctions6[length(plugins[pluginid].Registeredfunctions6)-1]:=f6;
result:=plugins[pluginid].nextid;
end;
7: begin
//disassemblerlines render
f7:=TPluginfunctionType7.Create;
f7.pluginid:=pluginid;
f7.functionid:=plugins[pluginid].nextid;
f7.callback:=Pfunction7(init).callbackroutine;
setlength(plugins[pluginid].RegisteredFunctions7,length(plugins[pluginid].RegisteredFunctions7)+1);
plugins[pluginid].RegisteredFunctions7[length(plugins[pluginid].RegisteredFunctions7)-1]:=f7;
result:=plugins[pluginid].nextid;
end;
8: begin
//autoassembler
f8:=TPluginfunctionType8.Create;
f8.pluginid:=pluginid;
f8.functionid:=plugins[pluginid].nextid;
f8.callback:=Pfunction8(init).callbackroutine;
setlength(plugins[pluginid].RegisteredFunctions8,length(plugins[pluginid].RegisteredFunctions8)+1);
plugins[pluginid].RegisteredFunctions8[length(plugins[pluginid].RegisteredFunctions8)-1]:=f8;
result:=plugins[pluginid].nextid;
end;
end;
inc(plugins[pluginid].nextid);
finally
pluginCS.leave;
end;
end;
function TPluginHandler.unregisterfunction(pluginid,functionid: integer): boolean;
var i,j: integer;
f: ^TPluginfunctionType0;
begin
//remove it
result:=false;
pluginCS.enter;
try
if pluginid>=length(plugins) then exit;
//function0 check
for i:=0 to length(plugins[pluginid].RegisteredFunctions0)-1 do
if plugins[pluginid].RegisteredFunctions0[i].functionid=functionid then
begin
if plugins[pluginid].RegisteredFunctions0[i].menuitem.Parent<>nil then
begin
if plugins[pluginid].RegisteredFunctions0[i].menuitem.Parent.Count=1 then
plugins[pluginid].RegisteredFunctions0[i].menuitem.Parent.Visible:=false;
end;
plugins[pluginid].RegisteredFunctions0[i].menuitem.Free;
plugins[pluginid].RegisteredFunctions0[i].Free;
for j:=i to length(plugins[pluginid].RegisteredFunctions0)-2 do
plugins[pluginid].RegisteredFunctions0[j]:=plugins[pluginid].RegisteredFunctions0[j+1];
setlength(plugins[pluginid].RegisteredFunctions0,length(plugins[pluginid].RegisteredFunctions0)-1);
result:=true;
exit;
end;
//function1 check
for i:=0 to length(plugins[pluginid].RegisteredFunctions1)-1 do
if plugins[pluginid].RegisteredFunctions1[i].functionid=functionid then
begin
if plugins[pluginid].RegisteredFunctions1[i].menuitem.Parent<>nil then
begin
if plugins[pluginid].RegisteredFunctions1[i].menuitem.Parent.Count=1 then
plugins[pluginid].RegisteredFunctions1[i].menuitem.Parent.Visible:=false;
end;
plugins[pluginid].RegisteredFunctions1[i].menuitem.Free;
plugins[pluginid].RegisteredFunctions1[i].Free;
for j:=i to length(plugins[pluginid].RegisteredFunctions1)-2 do
plugins[pluginid].RegisteredFunctions1[j]:=plugins[pluginid].RegisteredFunctions1[j+1];
setlength(plugins[pluginid].RegisteredFunctions1,length(plugins[pluginid].RegisteredFunctions1)-1);
result:=true;
exit;
end;
//function2 check
for i:=0 to length(plugins[pluginid].RegisteredFunctions2)-1 do
if plugins[pluginid].RegisteredFunctions2[i].functionid=functionid then
begin
plugins[pluginid].RegisteredFunctions2[i].Free;
for j:=i to length(plugins[pluginid].RegisteredFunctions2)-2 do
plugins[pluginid].RegisteredFunctions2[j]:=plugins[pluginid].RegisteredFunctions2[j+1];
setlength(plugins[pluginid].RegisteredFunctions2,length(plugins[pluginid].RegisteredFunctions2)-1);
result:=true;
exit;
end;
//function3 check (processwatcher)
for i:=0 to length(plugins[pluginid].Registeredfunctions3)-1 do
if plugins[pluginid].Registeredfunctions3[i].functionid=functionid then
begin
plugins[pluginid].Registeredfunctions3[i].Free;
for j:=i to length(plugins[pluginid].Registeredfunctions3)-2 do
plugins[pluginid].Registeredfunctions3[j]:=plugins[pluginid].Registeredfunctions3[j+1];
setlength(plugins[pluginid].Registeredfunctions3,length(plugins[pluginid].Registeredfunctions3)-1);
result:=true;
exit;
end;
//function4 check (changed pointers)
for i:=0 to length(plugins[pluginid].RegisteredFunctions4)-1 do
if plugins[pluginid].RegisteredFunctions4[i].functionid=functionid then
begin
plugins[pluginid].RegisteredFunctions4[i].Free;
for j:=i to length(plugins[pluginid].RegisteredFunctions4)-2 do
plugins[pluginid].RegisteredFunctions4[j]:=plugins[pluginid].RegisteredFunctions4[j+1];
setlength(plugins[pluginid].RegisteredFunctions4,length(plugins[pluginid].RegisteredFunctions4)-1);
result:=true;
exit;
end;
//function5 check
for i:=0 to length(plugins[pluginid].RegisteredFunctions5)-1 do
if plugins[pluginid].RegisteredFunctions5[i].functionid=functionid then
begin
if plugins[pluginid].RegisteredFunctions5[i].menuitem.Parent<>nil then
begin
if plugins[pluginid].RegisteredFunctions5[i].menuitem.Parent.Count=1 then
plugins[pluginid].RegisteredFunctions5[i].menuitem.Parent.Visible:=false;
end;
plugins[pluginid].RegisteredFunctions5[i].menuitem.Free;
plugins[pluginid].RegisteredFunctions5[i].Free;
for j:=i to length(plugins[pluginid].RegisteredFunctions5)-2 do
plugins[pluginid].RegisteredFunctions5[j]:=plugins[pluginid].RegisteredFunctions5[j+1];
setlength(plugins[pluginid].RegisteredFunctions5,length(plugins[pluginid].RegisteredFunctions5)-1);
result:=true;
exit;
end;
//function6 check
for i:=0 to length(plugins[pluginid].RegisteredFunctions6)-1 do
if plugins[pluginid].RegisteredFunctions6[i].functionid=functionid then
begin
if plugins[pluginid].RegisteredFunctions6[i].menuitem.Parent<>nil then
begin
if plugins[pluginid].RegisteredFunctions6[i].menuitem.Parent.Count=1 then
plugins[pluginid].RegisteredFunctions6[i].menuitem.Parent.Visible:=false;
end;
plugins[pluginid].RegisteredFunctions6[i].menuitem.Free;
plugins[pluginid].RegisteredFunctions6[i].Free;
for j:=i to length(plugins[pluginid].RegisteredFunctions6)-2 do
plugins[pluginid].RegisteredFunctions6[j]:=plugins[pluginid].RegisteredFunctions6[j+1];
setlength(plugins[pluginid].RegisteredFunctions6,length(plugins[pluginid].RegisteredFunctions6)-1);
result:=true;
exit;
end;
//function7 check
for i:=0 to length(plugins[pluginid].RegisteredFunctions7)-1 do
if plugins[pluginid].RegisteredFunctions7[i].functionid=functionid then
begin
plugins[pluginid].RegisteredFunctions7[i].Free;
for j:=i to length(plugins[pluginid].RegisteredFunctions7)-2 do
plugins[pluginid].RegisteredFunctions7[j]:=plugins[pluginid].RegisteredFunctions7[j+1];
setlength(plugins[pluginid].RegisteredFunctions7,length(plugins[pluginid].RegisteredFunctions7)-1);
result:=true;
exit;
end;
//function8 check
for i:=0 to length(plugins[pluginid].RegisteredFunctions8)-1 do
if plugins[pluginid].RegisteredFunctions8[i].functionid=functionid then
begin
plugins[pluginid].RegisteredFunctions8[i].Free;
for j:=i to length(plugins[pluginid].RegisteredFunctions8)-2 do
plugins[pluginid].RegisteredFunctions8[j]:=plugins[pluginid].RegisteredFunctions8[j+1];
setlength(plugins[pluginid].RegisteredFunctions8,length(plugins[pluginid].RegisteredFunctions8)-1);
result:=true;
exit;
end;
finally
pluginCS.leave;
end;
end;
procedure TPluginHandler.EnablePlugin(pluginid: integer);
var e: texportedfunctions;
enet: TExportedFunctionsDotNetV1 absolute e;
x: boolean;
begin
e:=exportedfunctions; //save it to prevent plugins from fucking it up
case plugins[pluginid].pluginversion of
1: e.sizeofExportedFunctions:=sizeof(Texportedfunctions1);
2: e.sizeofExportedFunctions:=sizeof(Texportedfunctions2);
3: e.sizeofExportedFunctions:=sizeof(Texportedfunctions3);
4: e.sizeofExportedFunctions:=sizeof(Texportedfunctions4);
5: e.sizeofExportedFunctions:=sizeof(Texportedfunctions5);
else
begin
if plugins[pluginid].dotnet then
begin
enet:=exportedfunctionsdotnet;
enet.sizeofExportedFunctions:=sizeof(TExportedFunctionsDotNetV1)
end
else
e.sizeofExportedFunctions:=sizeof(Texportedfunctions);
end;
end;
pluginCS.Enter;
try
if pluginid>=length(plugins) then exit;
if not plugins[pluginid].enabled then
begin
OutputDebugString('Calling EnablePlugin');
x:=plugins[pluginid].EnablePlugin(e,pluginid);
if not x then raise exception.Create(Format(rsErrorEnabling, [plugins[pluginid].dllname]));
plugins[pluginid].enabled:=true;
end;
finally
pluginCS.Leave;
end;
end;
procedure TPluginHandler.UnloadPlugin(pluginid: integer);
//will disable and unload the plugin
begin
pluginCS.Enter;
try
DisablePlugin(pluginid); //disable the plugin if it was active
FreeLibrary(plugins[pluginid].hmodule);
plugins[pluginid].dllname:='';
plugins[pluginid].filepath:='';
plugins[pluginid].name:='';
finally
pluginCS.Leave;
end;
end;
procedure TPluginHandler.DisablePlugin(pluginid: integer);
var i: integer;
begin
pluginCS.Enter;
try
if plugins[pluginid].enabled then
begin
if not plugins[pluginid].DisablePlugin() then raise exception.Create(Format(rsErrorDisabling, [plugins[pluginid].dllname]));
plugins[pluginid].enabled:=false;
//unregister all functions
// for i:=0 to
while length(plugins[pluginid].Registeredfunctions0)>0 do
unregisterfunction(pluginid,plugins[pluginid].Registeredfunctions0[0].functionid);
while length(plugins[pluginid].Registeredfunctions1)>0 do
unregisterfunction(pluginid,plugins[pluginid].Registeredfunctions1[0].functionid);
while length(plugins[pluginid].Registeredfunctions2)>0 do
unregisterfunction(pluginid,plugins[pluginid].Registeredfunctions2[0].functionid);
while length(plugins[pluginid].Registeredfunctions3)>0 do
unregisterfunction(pluginid,plugins[pluginid].Registeredfunctions3[0].functionid);
while length(plugins[pluginid].Registeredfunctions4)>0 do
unregisterfunction(pluginid,plugins[pluginid].Registeredfunctions4[0].functionid);
while length(plugins[pluginid].Registeredfunctions5)>0 do
unregisterfunction(pluginid,plugins[pluginid].Registeredfunctions5[0].functionid);
while length(plugins[pluginid].Registeredfunctions6)>0 do
unregisterfunction(pluginid,plugins[pluginid].Registeredfunctions6[0].functionid);
while length(plugins[pluginid].Registeredfunctions7)>0 do
unregisterfunction(pluginid,plugins[pluginid].Registeredfunctions7[0].functionid);
while length(plugins[pluginid].Registeredfunctions8)>0 do
unregisterfunction(pluginid,plugins[pluginid].Registeredfunctions8[0].functionid);
end;
finally
pluginCS.Leave;
end;
end;
function TPluginHandler.DotNetPluginGetPluginName(dllname: string): string;
var PInit: TPluginDotNetInitResult;
begin
DotNetExecuteClassMethod(dllname,'CESDK','CESDK','CEPluginInitialize', inttostr(ptruint(@PInit)));
result:=PInit.name;
end;
function TPluginHandler.GetPluginName(dllname:string):string;
var hmodule: thandle;
GetVersion: TGetVersion;
PluginVersion: TPluginVersion;
path: widestring;
isdotnet: boolean;
begin
result:='';
if uppercase(extractfileext(dllname))<>'.DLL' then raise exception.Create(Format(rsErrorLoadingOnlyDLLFilesAreAllowed, [dllname]));
{$ifdef windows}
if peinfo_isdotnetfile(dllname, isdotnet) then
if isdotnet then
exit(DotNetPluginGetPluginName(dllname));
{$endif}
hmodule:=loadlibrary(pchar(dllname));
{$ifdef windows}
if (hmodule=0) and assigned(AddDllDirectory) then
begin
path:=extractfiledir(dllname);
AddDllDirectory(pwidechar(@path[1]));
hmodule:=loadlibrary(pchar(dllname));
end;
{$endif}
if hmodule=0 then
raise exception.create(rsPlugThePluginDllCouldNotBeLoaded+inttostr(getlasterror));
GetVersion:=getprocaddress(hmodule,'CEPlugin_GetVersion');
if not assigned(GetVersion) then
getVersion:=getprocaddress(hmodule,'GetVersion');
if not assigned(GetVersion) then
raise exception.Create(Format(rsErrorLoadingTheDllIsMissingTheCEPlugin_GetVersionF, [dllname]));
if (getprocaddress(hmodule, 'CEPlugin_InitializePlugin')=nil) and (getprocaddress(hmodule, 'InitializePlugin')=nil) then raise exception.Create(Format(rsIsMissingTheCEPlugin_InitializePluginExport, [dllname]));
if (getprocaddress(hmodule, 'CEPlugin_DisablePlugin')=nil) and (getprocaddress(hmodule, 'DisablePlugin')=nil) then raise exception.Create(Format(rsIsMissingTheCEPlugin_DisablePluginExport, [dllname]));
if GetVersion(PluginVersion,sizeof(TPluginVersion)) then
result:=PluginVersion.pluginname;
freelibrary(hmodule);
end;
function TPluginHandler.GetPluginID(dllname:string):integer;
var dname: string;
i: integer;
begin
result:=-1;
dname:=uppercase(extractfilename(dllname));
pluginCS.Enter;
try
for i:=0 to length(plugins)-1 do
begin
if uppercase(plugins[i].dllname)=dname then
begin
result:=i;
exit;
end;
end;
finally
pluginCS.Leave;
end;
end;
function TPluginHandler.DotNetLoadPlugin(dllname:string):integer;
var initresult: TPluginDotNetInitResult;
begin
DotNetExecuteClassMethod(dllname,'CESDK','CESDK','CEPluginInitialize',inttostr(ptruint(@initresult)));
if initresult.version>currentpluginversion then
raise exception.Create(Format(rsErrorLoadingThisDllRequiresANewerVersionOfCeToFunc, [dllname]));
pluginCS.enter;
try
try
setlength(plugins,length(plugins)+1);
plugins[length(plugins)-1].dotnet:=true;
plugins[length(plugins)-1].pluginversion:=initresult.version;
plugins[length(plugins)-1].dllname:=extractfilename(dllname);
plugins[length(plugins)-1].filepath:=GetRelativeFilePath(dllname);
plugins[length(plugins)-1].hmodule:=0;
plugins[length(plugins)-1].name:=initresult.name;
plugins[length(plugins)-1].GetVersion:=initresult.GetVersion;
plugins[length(plugins)-1].EnablePlugin:=initresult.EnablePlugin;
plugins[length(plugins)-1].DisablePlugin:=initresult.DisablePlugin;
plugins[length(plugins)-1].nextid:=1;
result:=length(plugins)-1;
except
on e: exception do
begin
setlength(plugins,length(plugins)-1);
raise exception.create(e.message);
end;
end;
finally
pluginCS.leave;
end;
end;
function TPluginHandler.LoadPlugin(dllname:string):integer;
var hmodule: thandle;
GetVersion: TGetVersion;
PluginVersion: TPluginVersion;
s: string;
i: integer;
path: widestring;
isdotnet: boolean;
begin
result:=-1;
if uppercase(extractfileext(dllname))<>'.DLL' then raise exception.Create(Format(rsErrorLoadingOnlyDLLFilesAreAllowed, [dllname]));
s:=uppercase(extractfilename(dllname));
pluginCS.Enter;
try
for i:=0 to length(plugins)-1 do
begin
//check if it was loaded already or not
if s=uppercase(plugins[length(plugins)-1].dllname) then
begin
result:=i;
exit; //already in the list so no need to load again
end;
end;
finally
pluginCS.Leave;
end;
{$ifdef windows}
if peinfo_isdotnetfile(dllname, isdotnet) then
if isdotnet then
exit(DotNetLoadPlugin(dllname));
{$endif}
hmodule:=loadlibrary(pchar(dllname));
{$ifdef windows}
if (hmodule=0) and assigned(AddDllDirectory) then
begin
path:=ExtractFiledir(dllname);
AddDllDirectory(pwidechar(@path[1]));
hmodule:=loadlibrary(pchar(dllname));
end;
{$endif}
if hmodule=0 then
exit;
GetVersion:=getprocaddress(hmodule,'CEPlugin_GetVersion');
if not assigned(GetVersion) then
GetVersion:=getprocaddress(hmodule,'GetVersion');
if not assigned(GetVersion) then raise exception.Create(Format(rsErrorLoadingTheDllIsMissingTheCEPlugin_GetVersionE, [dllname]));
if GetVersion(PluginVersion,sizeof(TPluginVersion)) then
begin
if PluginVersion.version>currentpluginversion then
raise exception.Create(Format(rsErrorLoadingThisDllRequiresANewerVersionOfCeToFunc, [dllname]));
pluginCS.enter;
try
try
setlength(plugins,length(plugins)+1);
plugins[length(plugins)-1].dotnet:=false;
plugins[length(plugins)-1].pluginversion:=PluginVersion.version;
plugins[length(plugins)-1].dllname:=extractfilename(dllname);
plugins[length(plugins)-1].filepath:=GetRelativeFilePath(dllname);
plugins[length(plugins)-1].hmodule:=hmodule;
plugins[length(plugins)-1].name:=PluginVersion.pluginname;
plugins[length(plugins)-1].GetVersion:=getprocaddress(hmodule,'CEPlugin_GetVersion');
if not assigned(plugins[length(plugins)-1].GetVersion) then
plugins[length(plugins)-1].GetVersion:=GetProcAddress(hmodule, 'GetVersion');
plugins[length(plugins)-1].EnablePlugin:=getprocaddress(hmodule,'CEPlugin_InitializePlugin');
if not assigned(plugins[length(plugins)-1].EnablePlugin) then
plugins[length(plugins)-1].EnablePlugin:=GetProcAddress(hmodule, 'InitializePlugin');
plugins[length(plugins)-1].DisablePlugin:=getprocaddress(hmodule,'CEPlugin_DisablePlugin');
if not assigned(plugins[length(plugins)-1].DisablePlugin) then
plugins[length(plugins)-1].DisablePlugin:=GetProcAddress(hmodule, 'DisablePlugin');
plugins[length(plugins)-1].nextid:=1;
if not assigned(plugins[length(plugins)-1].EnablePlugin) then raise exception.Create(Format(rsIsMissingTheCEPlugin_InitializePluginExport, [dllname]));
if not assigned(plugins[length(plugins)-1].DisablePlugin) then raise exception.Create(Format(rsIsMissingTheCEPlugin_DisablePluginExport, [dllname]));
result:=length(plugins)-1;
except
on e: exception do
begin
setlength(plugins,length(plugins)-1);
raise exception.create(e.message);
end;
end;
finally
pluginCS.leave;
end;
end else raise exception.Create(Format(rsErrorLoadingTheGetVersionFunctionReturnedFALSE, [dllname]));
end;
procedure TPluginHandler.FillCheckListBox(clb: TCheckListbox);
var i,j: integer;
x:Tpathspecifier;
begin
if self=nil then exit;
j:=clb.count;
for i:=0 to clb.Count-1 do
Tpathspecifier(clb.Items.Objects[i]).Free;
clb.Clear;
pluginCS.Enter;
for i:=0 to length(plugins)-1 do
begin
x:=TPathSpecifier.Create;
x.path:=plugins[i].filepath;
j:=clb.Items.AddObject(plugins[i].dllname+':'+plugins[i].name,x);
clb.Checked[j]:=plugins[i].enabled;
end;
pluginCS.Leave;
end;
procedure TPluginHandler.handleAutoAssemblerPlugin(line: ppchar; phase: integer; id: integer);
var i,j: integer;
begin
pluginCS.Enter;
try
for i:=0 to length(plugins)-1 do
for j:=0 to length(plugins[i].RegisteredFunctions8)-1 do
begin
if plugins[i].pluginversion<=5 then
TPluginFunction8Version5(plugins[i].Registeredfunctions8[j].callback)(line,phase)
else
plugins[i].RegisteredFunctions8[j].callback(line,phase,id);
end;
finally
pluginCS.Leave;
end;
end;
procedure TPluginHandler.handledisassemblerContextPopup(address: ptruint);
var i,j: integer;
addressofmenuitemstring: pchar;
s: string;
show: bool;
begin
pluginCS.Enter;
try
for i:=0 to length(plugins)-1 do
for j:=0 to length(plugins[i].RegisteredFunctions6)-1 do
begin
s:=plugins[i].RegisteredFunctions6[j].menuitem.Caption;
addressofmenuitemstring:=@s[1];
show:=true;
if assigned(plugins[i].RegisteredFunctions6[j].callbackOnContext) then
begin
if plugins[i].pluginversion<=5 then
Tpluginfuntion6OnContextVersion5(plugins[i].RegisteredFunctions6[j].callbackOnContext)(address, @addressofmenuitemstring)
else
plugins[i].RegisteredFunctions6[j].callbackOnContext(address, @addressofmenuitemstring, @show);
end;
plugins[i].RegisteredFunctions6[j].menuitem.Caption:=addressofmenuitemstring;
plugins[i].RegisteredFunctions6[j].menuitem.Visible:=show;
end;
finally
pluginCS.Leave;
end;
end;
procedure TPluginHandler.handledisassemblerplugins(address: ptruint; addressStringPointer: pointer; bytestringpointer: pointer; opcodestringpointer: pointer; specialstringpointer: pointer; textcolor: PColor);
var i,j: integer;
begin
pluginCS.Enter;
try
for i:=0 to length(plugins)-1 do
for j:=0 to length(plugins[i].RegisteredFunctions7)-1 do
if assigned(plugins[i].RegisteredFunctions7[j].callback) then
plugins[i].RegisteredFunctions7[j].callback(address, addressStringPointer, bytestringpointer, opcodestringpointer, specialstringpointer, textcolor);
finally
pluginCS.Leave;
end;
end;
function TPluginHandler.handledebuggerplugins(devent: PDebugEvent):integer;
var i,j: integer;
begin
result:=0;
pluginCS.Enter;
try
for i:=0 to length(plugins)-1 do
for j:=0 to length(plugins[i].RegisteredFunctions2)-1 do
if assigned(plugins[i].RegisteredFunctions2[j].callback) then
if plugins[i].RegisteredFunctions2[j].callback(devent)=1 then result:=1;
finally
pluginCS.Leave;
end;
end;
function TPluginHandler.handlenewprocessplugins(processid: dword; peprocess:ptruint; created: boolean):boolean;
var i,j: integer;
begin
result:=true;
pluginCS.Enter;
try
for i:=0 to length(plugins)-1 do
for j:=0 to length(plugins[i].Registeredfunctions3)-1 do
begin
if plugins[i].pluginversion=1 then
TPluginFunction3Version1(plugins[i].Registeredfunctions3[j].callback)(processid,peprocess)
else
plugins[i].Registeredfunctions3[j].callback(processid,peprocess, created);
end;
finally
pluginCS.Leave;
end;
end;
function TPluginHandler.handlechangedpointers(section: integer):boolean;
var i,j: integer;
begin
if self=nil then exit(false);
if assigned(onAPIPointerChange) then
onAPIPointerChange(nil);
result:=true;
pluginCS.Enter;
try
for i:=0 to length(plugins)-1 do
for j:=0 to length(plugins[i].RegisteredFunctions4)-1 do
plugins[i].RegisteredFunctions4[j].callback(section);
finally
pluginCS.Leave;
end;
end;
destructor TPluginHandler.destroy;
var i,j: integer;
begin
pluginCS.Enter;
try
for i:=0 to length(plugins)-1 do
begin
try
UnloadPlugin(i);
except
end;
end;
finally
pluginCS.Leave;
end;
inherited destroy;
end;
constructor TPluginHandler.create;
var test: pchar;
begin
pluginCS:=TCriticalSection.Create;
exportedfunctions.sizeofExportedFunctions:=sizeof(TExportedFunctions);
exportedfunctions.showmessage:=@ce_showmessage;
exportedfunctions.registerfunction:=@ce_registerfunction;
exportedfunctions.unregisterfunction:=@ce_unregisterfunction;
exportedfunctions.OpenedProcessID:=@processhandler.processid;
exportedfunctions.OpenedProcessHandle:=@processhandler.processhandle;
exportedfunctions.GetMainWindowHandle:=@ce_GetMainWindowHandle;
exportedfunctions.AutoAssemble:=@ce_autoassemble;
exportedfunctions.assembler:=@ce_assembler;
exportedfunctions.disassembler:=@ce_disassembler;
exportedfunctions.ChangeRegistersAtAddress:=@ce_ChangeRegistersAtAddress;
exportedfunctions.InjectDLL:=@ce_injectdll;
exportedfunctions.freezemem:=@ce_freezemem;
exportedfunctions.unfreezemem:=@ce_unfreezemem;
exportedfunctions.fixmem:=nil; //obsolete
exportedfunctions.processlist:=@ce_processlist;
exportedfunctions.reloadsettings:=@ce_reloadsettings;
exportedfunctions.getaddressfrompointer:=@ce_getaddressfrompointer;
//pointers to the address that contains the pointers to the functions
{$ifdef windows}
exportedfunctions.ReadProcessMemory:=@@ReadProcessMemory;
exportedfunctions.WriteProcessMemory:=@@WriteProcessMemoryActual;
exportedfunctions.GetThreadContext:=@@GetThreadContext;
exportedfunctions.SetThreadContext:=@@SetThreadContext;
exportedfunctions.SuspendThread:=@@SuspendThread;
exportedfunctions.ResumeThread:=@@ResumeThread;
exportedfunctions.OpenProcess:=@@OpenProcess;
exportedfunctions.WaitForDebugEvent:=@@WaitForDebugEvent;
exportedfunctions.ContinueDebugEvent:=@@ContinueDebugEvent;
exportedfunctions.DebugActiveProcess:=@@DebugActiveProcess;
exportedfunctions.StopDebugging:=nil;
exportedfunctions.StopRegisterChange:=nil; //@@StopRegisterChange;
exportedfunctions.VirtualProtect:=@@VirtualProtect;
exportedfunctions.VirtualProtectEx:=@@VirtualProtectEx;
exportedfunctions.VirtualQueryEx:=@@VirtualQueryEx;
exportedfunctions.VirtualAllocEx:=@@VirtualAllocEx;
exportedfunctions.CreateRemoteThread:=@@CreateRemoteThread;
exportedfunctions.OpenThread:=@@OpenThread;
exportedfunctions.GetPEProcess:=@GetPEProcess;
exportedfunctions.GetPEThread:=@GetPEThread;
exportedfunctions.GetThreadsProcessOffset:=@GetThreadsProcessOffset;
exportedfunctions.GetThreadListEntryOffset:=@GetThreadListEntryOffset;
exportedfunctions.GetProcessnameOffset:=nil; //obsolete
exportedfunctions.GetDebugportOffset:=@GetDebugportOffset;
exportedfunctions.GetPhysicalAddress:=@GetPhysicalAddress;
exportedfunctions.ProtectMe:=nil;
exportedfunctions.GetCR4:=@GetCR4;
exportedfunctions.GetCR3:=@GetCR3;
exportedfunctions.SetCR3:=nil; //@@SetCR3;
exportedfunctions.GetSDT:=@GetSDT;
exportedfunctions.GetSDTShadow:=@GetSDTShadow;
exportedfunctions.setAlternateDebugMethod:=nil; //@@setAlternateDebugMethod;
exportedfunctions.getAlternateDebugMethod:=nil; //@@getAlternateDebugMethod;
exportedfunctions.DebugProcess:=nil; //@@DebugProcess;
exportedfunctions.ChangeRegOnBP:=nil; //@@ChangeRegOnBP;
exportedfunctions.RetrieveDebugData:=nil; //@@RetrieveDebugData;
exportedfunctions.StartProcessWatch:=@StartProcessWatch;
exportedfunctions.WaitForProcessListData:=@WaitForProcessListData;
exportedfunctions.GetProcessNameFromID:=@GetProcessNameFromID;
exportedfunctions.GetProcessNameFromPEProcess:=@GetProcessNameFromPEProcess;
exportedfunctions.KernelOpenProcess:=@dbk32functions.OP;
exportedfunctions.KernelReadProcessMemory:=@dbk32functions.RPM;
exportedfunctions.KernelWriteProcessMemory:=@dbk32functions.WPM;
exportedfunctions.KernelVirtualAllocEx:=@VQE;
exportedfunctions.IsValidHandle:=@IsValidHandle;
exportedfunctions.GetIDTCurrentThread:=@GetIDTCurrentThread;
exportedfunctions.GetIDTs:=@GetIDTs;
exportedfunctions.MakeWritable:=@MakeWritable;
exportedfunctions.GetLoadedState:=@GetLoadedState;
exportedfunctions.DBKSuspendThread:=@DBKSuspendThread;
exportedfunctions.DBKResumeThread:=@DBKResumeThread;
exportedfunctions.DBKSuspendProcess:=@DBKSuspendProcess;
exportedfunctions.DBKResumeProcess:=@DBKResumeProcess;
exportedfunctions.KernelAlloc:=@KernelAlloc;
exportedfunctions.GetKProcAddress:=@GetKProcAddress;
exportedfunctions.CreateToolhelp32Snapshot:=@@CreateToolhelp32Snapshot;
exportedfunctions.Process32First:=@@Process32First;
exportedfunctions.Process32Next:=@@Process32Next;
exportedfunctions.Thread32First:=@@Thread32First;
exportedfunctions.Thread32Next:=@@Thread32Next;
exportedfunctions.Module32First:=@@Module32First;
exportedfunctions.Module32Next:=@@Module32Next;
exportedfunctions.Heap32ListFirst:=@@Heap32ListFirst;
exportedfunctions.Heap32ListNext:=@@Heap32ListNext;
{$endif}
//give the address of the variable since there is a change they arn't initialized just yet...
exportedfunctions.mainform:=@mainform;
exportedfunctions.memorybrowser:=@memorybrowser;
//version2 init:
exportedfunctions.sym_nameToAddress:=@ce_sym_nameToAddress;
exportedfunctions.sym_addressToName:=@ce_sym_addressToName;
exportedfunctions.sym_generateAPIHookScript:=@ce_generateAPIHookScript;
//version3 init
{$ifdef windows}
exportedfunctions.loadDBK32:=@LoadDBK32;
exportedfunctions.loaddbvmifneeded:=@loaddbvmifneeded;
{$endif}
exportedfunctions.previousOpcode:=@ce_previousOpcode;
exportedfunctions.nextOpcode:=@ce_nextOpcode;
exportedfunctions.disassembleEx:=@ce_disassemble;
exportedfunctions.loadModule:=@ce_loadModule;
exportedfunctions.aa_AddExtraCommand:=@aa_AddExtraCommand;
exportedfunctions.aa_RemoveExtraCommand:=@aa_RemoveExtraCommand;
//version 4 init
exportedfunctions.createTableEntry:=@ce_createTableEntry;
exportedfunctions.getTableEntry:=@ce_getTableEntry;
exportedfunctions.memrec_setDescription:=@ce_memrec_setDescription;
exportedfunctions.memrec_getDescription:=@ce_memrec_getDescription;
exportedfunctions.memrec_getAddress:=@ce_memrec_getAddress;
exportedfunctions.memrec_setAddress:=@ce_memrec_setAddress;
exportedfunctions.memrec_getType:=@ce_memrec_getType;
exportedfunctions.memrec_setType:=@ce_memrec_setType;
exportedfunctions.memrec_getValue:=@ce_memrec_getValue;
exportedfunctions.memrec_setValue:=@ce_memrec_setValue;
exportedfunctions.memrec_getScript:=@ce_memrec_getScript;
exportedfunctions.memrec_setScript:=@ce_memrec_setScript;
exportedfunctions.memrec_isfrozen:=@ce_memrec_isfrozen;
exportedfunctions.memrec_freeze:=@ce_memrec_freeze;
exportedfunctions.memrec_unfreeze:=@ce_memrec_unfreeze;
exportedfunctions.memrec_setColor:=@ce_memrec_setColor;
exportedfunctions.memrec_appendtoentry:=@ce_memrec_appendtoentry;
exportedfunctions.memrec_delete:=@ce_memrec_delete;
exportedfunctions.getProcessIDFromProcessName:=@ce_getProcessIDFromProcessName;
exportedfunctions.openProcessEx:=@ce_openProcess;
exportedfunctions.debugProcessEx:=@ce_debugProcess;
exportedfunctions.pause:=@ce_pause;
exportedfunctions.unpause:=@ce_unpause;
exportedfunctions.debug_setBreakpoint:=@ce_debug_setBreakpoint;
exportedfunctions.debug_removeBreakpoint:=@ce_debug_removeBreakpoint;
exportedfunctions.debug_continueFromBreakpoint:=@ce_debug_continueFromBreakpoint;
exportedfunctions.closeCE:=@ce_closeCE;
exportedfunctions.hideAllCEWindows:=@ce_hideAllCEWindows;
exportedfunctions.unhideMainCEwindow:=@ce_unhideMainCEwindow;
exportedfunctions.createForm:=@ce_createForm;
exportedfunctions.form_centerScreen:=@ce_form_centerScreen;
exportedfunctions.form_hide:=@ce_form_hide;
exportedfunctions.form_show:=@ce_form_show;
exportedfunctions.form_onClose:=@ce_form_onClose;
exportedfunctions.createPanel:=@ce_createPanel;
exportedfunctions.createGroupBox:=@ce_createGroupBox;
exportedfunctions.createButton:=@ce_createButton;
exportedfunctions.createImage:=@ce_createImage;
exportedfunctions.image_loadImageFromFile:=@ce_image_loadImageFromFile;
exportedfunctions.image_transparent:=@ce_image_transparent;
exportedfunctions.image_stretch:=@ce_image_stretch;
exportedfunctions.createLabel:=@ce_createLabel;
exportedfunctions.createEdit:=@ce_createEdit;
exportedfunctions.createMemo:=@ce_createMemo;
exportedfunctions.createTimer:=@ce_createTimer;
exportedfunctions.timer_setInterval:=@ce_timer_setInterval;
exportedfunctions.timer_onTimer:=@ce_timer_onTimer;
exportedfunctions.control_setCaption:=@ce_control_setCaption;
exportedfunctions.control_getCaption:=@ce_control_getCaption;
exportedfunctions.control_setPosition:=@ce_control_setPosition;
exportedfunctions.control_getX:=@ce_control_getX;
exportedfunctions.control_getY:=@ce_control_getY;
exportedfunctions.control_setSize:=@ce_control_setSize;
exportedfunctions.control_getWidth:=@ce_control_getWidth;
exportedfunctions.control_getHeight:=@ce_control_getHeight;
exportedfunctions.control_setAlign:=@ce_control_setAlign;
exportedfunctions.control_onClick:=@ce_control_onClick;
exportedfunctions.object_destroy:=@ce_object_destroy;
exportedfunctions.messageDialog:=@ce_messageDialog;
exportedfunctions.speedhack_setSpeed:=@ce_speedhack_setSpeed;
//version 5
{$ifdef windows}
exportedfunctions.ExecuteKernelCode:=@ExecuteKernelCode;
exportedfunctions.UserdefinedInterruptHook:=@UserdefinedInterruptHook;
{$endif}
exportedfunctions.GetLuaState:=@plugin_GetLuaState;
exportedfunctions.MainThreadCall:=@pluginsync;
exportedfunctionsdotnet.sizeofExportedFunctions:=sizeof(exportedfunctionsdotnet);
exportedfunctionsdotnet.GetLuaState:=@plugin_GetLuaState;
exportedfunctionsdotnet.LuaRegister:=@lua_register;
exportedfunctionsdotnet.LuaPushClassInstance:=@luaclass_pushClass;
exportedfunctionsdotnet.ProcessMessages:=@plugin_processMessages;
exportedfunctionsdotnet.CheckSynchronize:=@plugin_CheckSynchronize;
end;
end.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。