I'm studying the NTFS filesystem, and I have a weird problem when trying to seek in \\.\PhysicalDrive0
with a huge number like 0xb2ec0000
(3001810944
). The $MFT
of my Windows partition is supposed to reside at that offset (which is the case).
When I was seeking from that number (even from the decimal form: 3001810944
), SetFilePointer
returned ERROR_NEGATIVE_SEEK
, so I decided to learn how negative numbers work in hexadecimal.
From that topic, I understood why 0xb2ec0000
was considered as negative, because it starts with b
. Powershell also recognizes it as negative:
PS A:\core> 0xb2ec0000
-1293156352
It can't only be a negative number, if we exclude the existence of negative numbers in hexadecimal, from some hexadecimal to decimal converters we realize that it's also equal to 3001810944
.
To successfully seek at offset 0xb2ec0000
, I decided to seek two times of 3001810944 / 2
bytes (1500905472
), it worked fine, but it's a problem if some natural numbers are considered as negative if they aren't in the given context, it doesn't seem normal at all.
And concerning the division, if I decide to do 0xb2ec0000 / 2
it outputs:
PS A:\core> 0xb2ec0000 / 2
-646578176
but
PS A:\core> 3001810944 / 2
1500905472
Here is the Rust code of the program:
You can reproduce the example by opening \\.\PhysicalDrive0
and seeking at offset 0xb2ec0000
:
extern "system"{
// [...]
fn CreateFileA(a: *const u8, b: u32, c: u32, d: *mut c_void, e: u32, f: u32, g: *mut c_void) -> *mut c_void;
fn SetFilePointer(a: *mut c_void, b: i64, c: *mut i32, d: u32) -> i32;
}
// [...]
let boot = CreateFileA(
"\\\\.\\PhysicalDrive0\0".as_ptr(),
25,
0x00000002 | 0x00000001,
null_mut(),
3,
128,
null_mut()
);
// [...] Calculating $MFT offset
let mft_offset: i64 = mft_logical_cluster * (bpb.wBytesPerSec * bpb.uchSecPerClust as u16) as i64 + (dsk_info.dwRelativeSector * 512) as i64;
println!("{:x}", mft_offset); // outputs 0xb2ec0000
if(SetFilePointer(boot,mft_offset,null_mut(),0) == -1){
println!("Error: {}", GetLastError()); // outputs 131
}