⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memscan.pas.svn-base

📁 这是一段游戏修改工具的源代码.ring3功能由dephi开发,驱动是C开发.希望对大家有帮助
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
unit memscan;
{
This unit will hold the class object used to control scanning
The old scanning routines will be moved out of cefuncproc and made object oriented into this class
Special care should be taken to add multithreaded scanning routines
}

interface

uses windows,sysutils, classes,ComCtrls,dialogs, cefuncproc,
     newkernelhandler, math, SyncObjs, SaveFirstScan, firstscanhandler,
     autoassembler;

type TScanOption=(soUnknownValue,soExactValue,soValueBetween,soBiggerThan,soSmallerThan, soIncreasedValue, soIncreasedValueBy, soDecreasedValue, soDecreasedValueBy, soChanged, soUnchanged, soSameAsFirst, soCustom);
type TScanType=(stNewScan, stFirstScan, stNextScan);
type TRoundingType=(rtRounded,rtExtremerounded,rtTruncated);
type TVariableType=(vtByte, vtWord, vtDword, vtQword, vtSingle, vtDouble, vtString, vtByteArray, vtBinary, vtAll, vtCustom);
type TCustomScanType=(cstNone, cstAutoAssembler, cstCPP, cstDLLFunction);

type TCheckRoutine=function(newvalue,oldvalue: pointer):boolean of object;
type TStoreResultRoutine=procedure(address: dword; oldvalue: pointer) of object;
type TFlushRoutine=procedure of object;



type
  TMemScan=class;
  TScanController=class;

  Tscanfilewriter=class(tthread)
  {
  workerthread:
  This class is used because it is more efficient to write only one file at a
  time. It will aquire a critical section when writing a file to acomplish that

  also, not that it matters much, since you eventually have to wait for the
  write anyhow, a double buffered result list so it can keep scanning while the
  list is being saved.
  }
  private
    scancontroller: TScanController;
    addressfile: TFilestream;
    memoryfile: TFilestream;
//    cAddressFile,cMemoryFile: TCompressionStream;

    addressbuffer: pointer;
    memorybuffer: pointer;
    addressSize: dword;
    memorySize: dword;



    datawritten: tevent; //event that is set when the thread has finished writing
    dataavailable:tevent; //event that is set when there is a buffer to save
  public
    procedure execute; override;
    procedure writeresults(addressbuffer,memorybuffer: pointer; addressSize,memorySize: dword); //writes the results of address and memory
    procedure flush;
    constructor create(scancontroller:TScanController; addressfile,memoryfile:TFileStream);
    destructor destroy; override;
  end;


  TScanner=class(tthread)
  {
    The scanner class will scan a specified range of memory
  }
  private
    CheckRoutine: TCheckRoutine;
    StoreResultRoutine: TStoreResultRoutine;
    FlushRoutine: TFlushRoutine; //pointer to routine used to flush the buffer, generic, string, etc...
    scanWriter: Tscanfilewriter;
    firstscanhandler: TFirstscanhandler;

    customprologue: procedure; stdcall; //customscan call before scan starts
    customepilogue: procedure; stdcall; //customscan call after scan ends

    found :dword;

    value,value2: int64;
    svalue,svalue2: single;
    dvalue,dvalue2: double;
    minsvalue,maxsvalue: single;
    mindvalue,maxdvalue: double;
    floataccuracy: integer; //number of digits after the decimal seperator

    CurrentAddressBuffer: pointer;
    CurrentFoundBuffer: pointer; //generic buffer that points to where the memory can be found
    SecondaryFoundBuffer: pointer;   //current gets swapped with these ones after a write
    SecondaryAddressBuffer: pointer;

    //binary scan
    bitmask: int64; //contains the bit string where * is replaced with a 0
    andmask: int64; //contains the bit string where 1 and 0 is 1 and * is 0
    binaryresults: array [0..7] of boolean; //after a byte is checked this contains which startbits match

    //array of bytes
    abs_arraylength: integer; //optimization so no need to call length()
    abs_arraytofind: TBytes;

    //all
    typesmatch: array [vtByte..vtDouble] of boolean;  //will get set depending if that type matches the current address or not

    //check routines:
    function ByteExact(newvalue,oldvalue: pointer): boolean;
    function ByteBetween(newvalue,oldvalue: pointer): boolean;
    function ByteBiggerThan(newvalue,oldvalue: pointer): boolean;
    function ByteSmallerThan(newvalue,oldvalue: pointer): boolean;
    function ByteIncreasedValue(newvalue,oldvalue: pointer): boolean;
    function ByteIncreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function ByteDecreasedValue(newvalue,oldvalue: pointer): boolean;
    function ByteDecreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function ByteChanged(newvalue,oldvalue: pointer): boolean;
    function ByteUnChanged(newvalue,oldvalue: pointer): boolean;

    function WordExact(newvalue,oldvalue: pointer): boolean;
    function WordBetween(newvalue,oldvalue: pointer): boolean;
    function WordBiggerThan(newvalue,oldvalue: pointer): boolean;
    function WordSmallerThan(newvalue,oldvalue: pointer): boolean;
    function WordIncreasedValue(newvalue,oldvalue: pointer): boolean;
    function WordIncreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function WordDecreasedValue(newvalue,oldvalue: pointer): boolean;
    function WordDecreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function WordChanged(newvalue,oldvalue: pointer): boolean;
    function WordUnChanged(newvalue,oldvalue: pointer): boolean;

    function DWordExact(newvalue,oldvalue: pointer): boolean;
    function DWordBetween(newvalue,oldvalue: pointer): boolean;
    function DWordBiggerThan(newvalue,oldvalue: pointer): boolean;
    function DWordSmallerThan(newvalue,oldvalue: pointer): boolean;
    function DWordIncreasedValue(newvalue,oldvalue: pointer): boolean;
    function DWordIncreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function DWordDecreasedValue(newvalue,oldvalue: pointer): boolean;
    function DWordDecreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function DwordChanged(newvalue,oldvalue: pointer): boolean;
    function DwordUnChanged(newvalue,oldvalue: pointer): boolean;


    function QWordExact(newvalue,oldvalue: pointer): boolean;
    function QWordBetween(newvalue,oldvalue: pointer): boolean;
    function QWordBiggerThan(newvalue,oldvalue: pointer): boolean;
    function QWordSmallerThan(newvalue,oldvalue: pointer): boolean;
    function QWordIncreasedValue(newvalue,oldvalue: pointer): boolean;
    function QWordIncreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function QWordDecreasedValue(newvalue,oldvalue: pointer): boolean;
    function QWordDecreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function QWordChanged(newvalue,oldvalue: pointer): boolean;
    function QwordUnChanged(newvalue,oldvalue: pointer): boolean;

    function SingleExact(newvalue,oldvalue: pointer): boolean;
    function SingleBetween(newvalue,oldvalue: pointer): boolean;
    function SingleBiggerThan(newvalue,oldvalue: pointer): boolean;
    function SingleSmallerThan(newvalue,oldvalue: pointer): boolean;
    function SingleIncreasedValue(newvalue,oldvalue: pointer): boolean;
    function SingleIncreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function SingleDecreasedValue(newvalue,oldvalue: pointer): boolean;
    function SingleDecreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function SingleChanged(newvalue,oldvalue: pointer): boolean;
    function singleUnChanged(newvalue,oldvalue: pointer): boolean;

    function DoubleExact(newvalue,oldvalue: pointer): boolean;
    function DoubleBetween(newvalue,oldvalue: pointer): boolean;
    function DoubleBiggerThan(newvalue,oldvalue: pointer): boolean;
    function DoubleSmallerThan(newvalue,oldvalue: pointer): boolean;
    function DoubleIncreasedValue(newvalue,oldvalue: pointer): boolean;
    function DoubleIncreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function DoubleDecreasedValue(newvalue,oldvalue: pointer): boolean;
    function DoubleDecreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function DoubleChanged(newvalue,oldvalue: pointer): boolean;
    function DoubleUnChanged(newvalue,oldvalue: pointer): boolean;

    function AllExact(newvalue,oldvalue: pointer):boolean; //check byte,word,dword,qword,single and float
    function AllBetween(newvalue,oldvalue: pointer): boolean;
    function AllBiggerThan(newvalue,oldvalue: pointer): boolean;
    function AllSmallerThan(newvalue,oldvalue: pointer): boolean;
    function AllIncreasedValue(newvalue,oldvalue: pointer): boolean;
    function AllIncreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function AllDecreasedValue(newvalue,oldvalue: pointer): boolean;
    function AllDecreasedValueBy(newvalue,oldvalue: pointer): boolean;
    function AllChanged(newvalue,oldvalue: pointer): boolean;
    function AllUnchanged(newvalue,oldvalue: pointer): boolean;

    //following types only have exact: Array of byte, binary and string
    function ArrayOfByteExact(newvalue,oldvalue: pointer):boolean;
    function BinaryExact(newvalue,oldvalue: pointer):boolean;
    function CaseSensitiveAnsiStringExact(newvalue,oldvalue: pointer):boolean;
    function CaseInsensitiveAnsiStringExact(newvalue,oldvalue: pointer):boolean;
    function CaseSensitiveUnicodeStringExact(newvalue,oldvalue: pointer):boolean;
    function CaseInsensitiveUnicodeStringExact(newvalue,oldvalue: pointer):boolean;



    //save macthing address routines:
    procedure GenericSaveResult(address: dword; oldvalue: pointer); //only use as last resort : Call to copymemory just to store one entry
    procedure allSaveResult(address: dword; oldvalue: pointer);
    procedure binarySaveResult(address: dword; oldvalue: pointer);
    procedure arrayOfByteSaveResult(address: dword; oldvalue: pointer);
    procedure ByteSaveResult(address: dword; oldvalue: pointer);
    procedure WordSaveResult(address: dword; oldvalue: pointer);
    procedure DWordSaveResult(address: dword; oldvalue: pointer);    
    procedure QWordSaveResult(address: dword; oldvalue: pointer);
    procedure SingleSaveResult(address: dword; oldvalue: pointer);
    procedure DoubleSaveResult(address: dword; oldvalue: pointer);    

    //flush routines
    procedure genericFlush; //generic routine for flushing the buffer
    procedure stringFlush; //don't save the memory
    procedure binaryFlush; //don't save memory AND use foundaddressb for results
    procedure allFlush;


    procedure configurescanroutine; //parses scanvalue1,2 according to the VariableType and scanoptions
    procedure FirstScanmem(base:dword; buffer: pointer; size: integer); //routine that gets a buffer and saves all the results it finds in the buffer (For firstscan)
    procedure FirstNextScanmem(base:dword; buffer,oldbuffer: pointer; size: integer);

    procedure nextnextscanmemall(addresslist: pointer; oldmemory: pointer; chunksize: integer);
    procedure nextnextscanmembinary(addresslist: pointer; chunksize: integer);
    procedure nextnextscanmem(addresslist: pointer; oldmemory: pointer; chunksize: integer);

    procedure firstscan; //copy the given range to the memory region
    procedure firstnextscan; //routine used when the results list contains nothing but a indicator a unknown scan was done
    procedure nextnextscan; //routine used when the results list contains addresses

  public
    OwningScanController: TScanController;
    Addressfile: TFilestream; //CheatEngineDir+'Addresses'+ThreadID.TMP'
    MemoryFile: TFileStream;  //CheatEngineDir+'Memory'+ThreadID.TMP'
    Addressfilename: string;
    MemoryFilename: string;

    roundingtype: TRoundingtype;
    hexadecimal: boolean;
    binaryStringAsDecimal: boolean;
    readonly: boolean;
    fastscan: boolean;
    unicode: boolean;
    caseSensitive: boolean;
    fastscanalignsize: integer;
    variablesize: integer;
    scanvalue1,scanvalue2: string;
    widescanvalue1: widestring;
    scanOption: TScanOption;
    variableType: TVariableType;
    scanType: TScanType; //defines if it's a firstscan or next scan. (newscan is ignored)
    useNextNextscan: boolean; //determines to use the nextNextScan or firstNextScan

    customscanscript: tstrings; //holds the info for the custom type, script for AA, script for CScript, 2 lines for dll: dllname+function
    customscantype: TCustomScanType;
    customscanAllocArray: TCEAllocArray;




    //thread controlling variables:
    isdone: boolean; //will get set to true when the thread finishes normally
    haserror: boolean;
    errorstring: string;

    //region related scans:
    //startregion and stopregion
    _startregion: integer;
    _stopregion: integer;
    maxregionsize: dword; //max size of buffer to be allocated when not unknown scan

    //recreated memory region list for this specific range, can be used to see which regions where only half read
    memRegions: TMemoryregions;
    memRegionPos: integer;

    startaddress: dword; //specific start for this this thread
    stopaddress: dword; //specific stop for this thread, if not fastscan and another thread continue from here, may add some overlopping bytes

    //exact address scans:
    startentry: integer; //index in the address list
    stopentry: integer; //"   "

    //general:
    scanned: dword; //total memory/addresses scanned by this routine
    totalfound: dword;

    scannernr: integer;

    procedure execute; override;
    constructor create(suspended: boolean);
    destructor destroy; override;
  end;

  TScanController=class(tthread)
  {
    The ScanController will configure the scanners and wait till they are done, mainly a idle thread
  }
  private
    threadcount: integer;
    addressFile: TFileStream;
    memoryFile: TFileStream;
    savescannerresults: boolean; //tells the epilogue to save the results to addressfile and memoryfile

    procedure updategui;
    procedure errorpopup;
    procedure firstScan;
    procedure nextScan;
    procedure firstnextscan; //rotine used when the results list contains nothing but a indicator a unknown scan was done
    procedure nextnextscan; //routine used when the results list contains addresses
    procedure fillVariableAndFastScanAlignSize; //fills in the variablesize and fastscanalignsizevariables, used for firstscan and firstnextscan
  public
    OwningMemScan: TMemScan;
    
    resultsaveCS: tcriticalsection; //critical section the scanfilewriter objects use to determine if there is another scanthread writing
    scannersCS: TCriticalSection; //Critican section used aty the end of the scancontroller thread, when the scanners are being destroyed
    scanners: array of tscanner;

    totalAddresses: dword; //how many addresses it will have to scan

    roundingtype: TRoundingType;
    hexadecimal: boolean;
    binaryStringAsDecimal: boolean;
    readonly: boolean;
    fastscan: boolean;
    unicode: boolean;
    casesensitive: boolean;
    fastscanalignsize: integer;
    variablesize: integer;
    scanvalue1,scanvalue2: string;
    startaddress: dword; //start for the whole scan
    stopaddress: dword; //stop of the whole scan
    scanOption: TScanOption;
    variableType: TVariableType;
    scanType: TScanType; //defines if it's a firstscan or next scan. (newscan is ignored)

    customscanscript: tstrings; //holds the info for the custom type, script for AA, script for CScript, 2 lines for dll: dllname+function
    customscantype: TCustomScanType;    

    //memregion info
    memregion: TMemoryregions;  //scanners have access to this, but make sure to NOT WRITE it
    memRegionPos: Integer;



    //thread controlling variables:
    isdone: boolean; //will get set to true when the thread finishes normally
    haserror: boolean;
    errorstring: string;

    //messages
    notifywindow: thandle;
    notifymessage: integer;
    procedure execute; override;
    constructor create(suspended: boolean);
    destructor destroy; override;
  end;

  TMemScan=class
  {
    Configures the gui and related objects and launch TScanner objects with those objects
  }
  private
    previousMemoryBuffer: pointer;
    scanController: TScanController; //thread that configures the scanner threads and wait till they are done
    SaveFirstScanThread: TSaveFirstScanThread; //thread that will save the results of the first scan that can be used for "same as first scan" scans
    memRegion: TMemoryRegions;  //after a scan the contents of controller gets copied to here
    memRegionPos: integer;

    progressbar: TProgressBar;
    notifywindow: thandle;
    notifymessage: integer;

    currentVariableType: TVariableType;
    found: uint64;

    //string stuff:
    stringUnicode: boolean;
    stringLength:  integer;

    //binary stuff:
    binaryLength:  integer;

    //array stuff:
    arrayLength:   integer;


    FLastScanType: TScanType;
  public
    function GetProgress(var totaladdressestoscan:dword; var currentlyscanned: dword):integer;
    function GetErrorString: string;
    function GetFoundCount: uint64;
    function Getbinarysize: int64; //returns the number of bits of the current type
    procedure TerminateScan;
    procedure newscan; //will clean up the memory and files
    procedure firstscan(scanOption: TScanOption; VariableType: TVariableType; roundingtype: TRoundingType; scanvalue1, scanvalue2: string; startaddress,stopaddress: dword; fastscan,readonly,hexadecimal,binaryStringAsDecimal,unicode,casesensitive: boolean; customscanscript: tstrings; customscantype: TCustomScanType); //first scan routine, e.g unknown initial value, or exact scan
    procedure NextScan(scanOption: TScanOption; roundingtype: TRoundingType; scanvalue1, scanvalue2: string; startaddress,stopaddress: dword; fastscan,readonly,hexadecimal,binaryStringAsDecimal,unicode,casesensitive: boolean; customscanscript: tstrings; customscantype: TCustomScanType); //next scan, determine what kind of scan and give to firstnextscan/nextnextscan

    constructor create(progressbar: TProgressbar;notifywindow: thandle; notifymessage: integer);
    destructor destroy; override;

    property LastScanType: TScanType read FLastScanType;
  end;

implementation

uses StrUtils;

var foundaddress: byte;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -