Crc Check My Program in Memory ?

k6__
k6__ used Ask the Experts™
on
How can i get the Crc32 Value of my
program in memory ? (i mean that i need
to get Crc32 Value of Memory that has
taken of my program..) so to avoid to
been cracked using Memory Proccess Patchers ?

Thanx
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
hi k6
 see here:
http://www.efg2.com/lab/Mathematics/CRC.htm

links to many crc sources etc..
Regards Barry


Commented:
from above link
this good example with crc16,crc32 etc. :

http://www.efg2.com/lab/Mathematics/CRCDelphi.ZIP

and a unit off dejanews:

unit CRC;
 
// implementiert 3 CRC-Routinen zur Berechnung der Prüfsumme nach dem // Cyclic Redundancy Check Algorithmus
// siehe DDJ April 97 pp103.
{$R-}
 
interface
 
function CalculateCRC16(const Data; Length: LongWord): Word;
function CalculateXYZModemCRC16(const Data; Length: LongWord): Word; function CalculateCRC32(const Data; Length: LongWord): LongWord;
 
implementation
 
type
  TCRC16Table = array[0..255] of Word;
  TCRC32Table = array[0..255] of LongWord;
  TBytes = array[0..MaxInt - 1] of Byte;
 
 
procedure BuildCRC16Table(var CRC16Table: TCRC16Table);
var
  i, j: word;
  CRC: word;
begin
  for i := 0 to 255 do
  begin
    CRC := (i shl 8);
    for j := 0 to 7 do
    begin
      if (crc and $8000) = $8000 then
        crc := (crc shl 1) xor $1021
      else
        crc := (crc shl 1);
    end;
    CRC16Table[i]:=crc;
  end;
end;
 
procedure BuildCRC32Table(var CRC32Table: TCRC32Table);
var
  i, j: LongWord;
  CRC: LongWord;
begin
  for i:=0 to 255 do
  begin
    CRC:=(i shl 24);
    for j:=0 to 7 do
    begin
      if (crc and $80000000)=$80000000 then
        crc:=(crc shl 1) xor $04C11DB7
      else
        crc:=(crc shl 1);
    end;
    CRC32Table[i]:=crc;
  end;
end;
 
function CalculateCRC16(const Data; Length: LongWord): Word;
var
  CRC16Table: TCRC16Table;
  CRC16: word;
  index: byte;
  i:LongWord;
begin
  BuildCRC16Table(CRC16Table);
  CRC16:=0;
  for i:=0 to Length-1 do
  begin
    index := (CRC16 shr 8) and $FF;
    CRC16 := CRC16Table[Index] xor (CRC16 shl 8) xor TBytes(Data)[i];   end;
  Result := CRC16;
end;
 
function CalculateXYZModemCRC16(const Data; Length: LongWord): Word; var
  CRC16Table: TCRC16Table;
  CRC16: word;
  index: byte;
  i:LongWord;
begin
  BuildCRC16Table(CRC16Table);
  CRC16:=$FFFF;
  for i:=0 to Length-1 do
  begin
    index := ((CRC16 shr 8) xor TBytes(Data)[i]) and $FF;
    CRC16 := CRC16Table[Index] xor (CRC16 shl 8);
  end;
  Result := CRC16;
end;
 
function CalculateCRC32(const Data; Length: LongWord): LongWord; var
  CRC32Table: TCRC32Table;
  CRC32: LongWord;
  index: byte;
  i:LongWord;
begin
  BuildCRC32Table(CRC32Table);
  CRC32:=$FFFFFFFF;
  for i:=0 to Length-1 do
  begin
    index := ((CRC32 shr 24) xor TBytes(Data)[i]) and $FF;
    CRC32 := CRC32Table[Index] xor (CRC32 shl 8);
  end;
  Result := CRC32;
end;
 

Commented:
Barry, that's only the first half of the problem. If you now explain to k6, how he can use this function on his code in memory, your answer will be complete...   :-)

Regards, Madshi.
OWASP: Threats Fundamentals

Learn the top ten threats that are present in modern web-application development and how to protect your business from them.

Author

Commented:
Ermh.. i have the code to get crc32
from a string and a file (with a precalculated table/array)
.... The Major problem is to as Madshi
said :

Find Where my program is on the memory (Get the end/start Addresses) and
start calculate the Crc32 like i do
on a sigle file so if someone tries
to hack it into memory (using process/memory patchers) the it will
return wrong Crc =). Thats why i need
that!

Thanx

Commented:
sorry i wasnt reading q properly .
Barry wants #1 back bad!!! :o)
Cheers,

Raymond.

Commented:
Well, this could be a beginning. Hmm... I guess it reads a bit too much memory, you'll have to test whether it works or not... (You can give in GetCurrentProcessID in your case).

function ReadProcMem(processID: dword) : string;
var ph  : dword;
    p1  : pointer;
    mbi : TMemoryBasicInformation;
    dw1 : dword;
begin
  result := '';
  ph := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, processID);
  if ph <> 0 then
    try
      p1 := nil;
      while VirtualQueryEx(ph, p1, mbi, sizeOf(TMemoryBasicInformation)) = sizeOf(TMemoryBasicInformation) do begin
        if (mbi.BaseAddress <> nil) and (mbi.BaseAddress = mbi.AllocationBase) then begin
          SetLength(result, mbi.RegionSize);
          if (not ReadProcessMemory(ph, mbi.BaseAddress, pointer(result), mbi.RegionSize, dw1)) or
             (dw1 <> mbi.RegionSize) then
            result := '';
          break;
        end;
        p1 := pointer(cardinal(p1) + mbi.RegionSize);
      end;
    finally CloseHandle(ph) end;
end;

Regards, Madshi.

Author

Commented:
Let's try..

Author

Commented:
I've Tried ReadProcMem(GetCurrentProcessID) and it returns
an 'A'!

Madshi ?

Commented:
Hey, it's no real "string" (that is pure text) that you get from this function, it's BINARY data. That means you can't put it into an edit or memo field.
Look at Length(ReadProcMem(GetCurrentProcessID)) to find out that the string contains much more than just one character.

If you use this function declaration:

function CalculateCRC32(const Data; Length: LongWord): LongWord;

You should call it all like this:

  str := ReadProcMem(GetCurrentProcessID);
  crc32 := CalculateCRC32(pointer(str)^, length(str));

Regards, Madshi.

Author

Commented:
hmm..
ShowMessage(IntToStr(Length(ReadProcMem(GetCurrentProcessID))));
= 4096 .. my application is bigger than
4 kb don't you thing ?
Commented:
Hmmm, right... There seems to be a bug in my function. This one should work:

function GetModuleNtHeaders(module: cardinal) : PImageNtHeaders;
const CENEWHDR = $003C;          // offset of new EXE header
      CEMAGIC  = $5A4D;          // old EXE magic id:  'MZ'
      CPEMAGIC = $4550;          // NT portable executable
begin
  result := nil;
  try
    if TPWord(module)^ = CEMAGIC then begin
      result := pointer(module + TPWord(module + CENEWHDR)^);
      if result^.signature <> CPEMAGIC then
        result := nil;
    end;
  except result := nil end;
end;

function GetMyProcMem : string;
begin
  with GetModuleNtHeaders(HInstance)^.OptionalHeader do begin
    SetLength(result, SizeOfCode);
    Move(pointer(HInstance + BaseOfCode)^, pointer(result)^, SizeOfCode);
  end;
end;

Regards, Madshi.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial