This works great if it isn't checking itself.

If I change the value of checksum, then the comparison fails.
How can I fix this?



.data

Orig_ChkSum    dd  0CEBFh ; value of UNaltered file

.code

invoke MapFileAndCheckSumA, ADDR FileName,ADDR headerSum,ADDR checkSum

.if eax == CHECKSUM_OPEN_FAILURE

invoke  MessageBox,NULL,addr Open_Failure, addr AppName,MB_OK
invoke ExitProcess,0

.endif

mov eax, checkSum    ; move value to EAX

.if eax == Orig_ChkSum ; Check if file has been altered
invoke  MessageBox, NULL, addr File_OK, addr AppName,MB_OK

.else

  invoke MessageBox,NULL,addr FileChanged,addr AppName,MB_OK

.endif

Posted on 2010-09-14 21:35:18 by skywalker
One approach could be using just headerSum instead of your internal Orig_ChkSum (but make sure your linker is generating it instead of just putting zero). The second, after studying the checksum algorithm, would be constructing a byte sequence that compensates the introduction of Orig_ChkSum (if it were a simple 8-bit byte summation for instance, it would be quite trivial to do). And the last option would be doing the checksum(s) yourself with custom algorithm(s).
Posted on 2010-09-14 21:52:12 by LocoDelAssembly
This function returns two checksum values.
The headerSum variable is the checksum that was present in the file already.
The checkSum variable is the calculated checksum of the file.
These two values SHOULD match each other, AND your hardcoded Orig_ChkSum variable... all three would be the same if the file content has not been modified.
All you need to do is have a look at the checkSum value it returned and use that for the Orig_ChkSum value.
Was this so hard?

Although its worth noting that a CRC32 checksum is not a secure way to fly, since it is VERY easy to adjust the file data such that the checksum matches.
Posted on 2010-09-14 21:53:08 by Homer

One approach could be using just headerSum instead of your internal Orig_ChkSum (but make sure your linker is generating it instead of just putting zero). The second, after studying the checksum algorithm, would be constructing a byte sequence that compensates the introduction of Orig_ChkSum (if it were a simple 8-bit byte summation for instance, it would be quite trivial to do). And the last option would be doing the checksum(s) yourself with custom algorithm(s).


Thanks.

My linker is only putting in zeros for the HeaderSum.
How do I fix that?

Posted on 2010-09-14 22:43:53 by skywalker
I got it fixed with link.... /RELEASE

I'll work on an algorithm for checking parts of code most likely to be changed.


mov eax, CheckSum    ; move value to EAX
mov ebx, HeaderSum
cmp eax,ebx
jne finish


Posted on 2010-09-14 23:25:42 by skywalker
... all three would be the same if the file content has not been modified.
All you need to do is have a look at the checkSum value it returned and use that for the Orig_ChkSum value.
Was this so hard?
The hard part is how do you manage to store in Orig_ChkSum a value that at the same time will match that of headerSum AND ALSO checkSum (take in mind that the checksum process will take Orig_ChkSum itself as part of the calculation just like any other byte in the file). AFAIK, with Windows' checksum you should be able to construct some complementary byte sequence to be able to nullify the effects over headerSum by storing Orig_ChkSum, but still not as trivial* as just copying headerSum into Orig_ChkSum without doing anything else.

*I don't mean computational complexity here, actually it is possible to get this in a very short time.
Posted on 2010-09-15 00:14:11 by LocoDelAssembly
Simply take the CALCULATED checksum and call it your original checksum value - at the time of building the exe, this is the valid value, and will not change by itself. Not difficult, no need to get confused.

Posted on 2010-09-15 00:35:12 by Homer

Simply take the CALCULATED checksum and call it your original checksum value - at the time of building the exe, this is the valid value, and will not change by itself. Not difficult, no need to get confused.




I am not confused Homer.

That is what I did above.

Posted on 2010-09-15 09:24:44 by skywalker

... all three would be the same if the file content has not been modified.
All you need to do is have a look at the checkSum value it returned and use that for the Orig_ChkSum value.
Was this so hard?
The hard part is how do you manage to store in Orig_ChkSum a value that at the same time will match that of headerSum AND ALSO checkSum (take in mind that the checksum process will take Orig_ChkSum itself as part of the calculation just like any other byte in the file).


I solved the problem. I attached a pic.

Attachments:
Posted on 2010-09-15 09:34:16 by skywalker
skywalker, good, seems you used the first method.

Homer, are you aware that we are talking about self-checking with MapFileAndCheckSum?

Take a look at this:

struct DataBlock
  data rb 4092
  checksum db ?
ends

proc checksum pByteArray:DWORD, size:DWORD
xor eax, eax
mov ecx, Posted on 2010-09-15 09:57:47 by LocoDelAssembly
LocoDelAssembly,

The problem is slightly deeper: IMAGE_FILE_HEADER.TimeDateStamp is checksummed too.

As to PE checksum, it's based on sum of all image dwords (trailing bytes are regarded as being padded with 0). Hence if you decrement one (naturally aligned) dword (without overflow) and increment another, PE checksum stays the same.
Posted on 2010-09-15 10:22:46 by baldr