Copy Link
Add to Bookmark
Report
NULL mag Issue 04 12 Byte Counting
__ _ __ _ _ __
______\ \_\\_______________________\///__________________________//_/ /______
\___\ /___/
| .__ __ |
| | ___ __________/ |________ |
| \ \/ / ____/\ __\_ __ \ |
; > < <_| | | | | | \/ ;
: /__/\_ \__ | |__| |__| :
. \/ |__| .
. .
: H/Q Another Droid BBS - andr01d.zapto.org:9999 :
; ;
+ --- -- - . - --- --- --- - . - -- --- +
: :
| Byte Counting... |
: :
` --- -- - . - --- --- --- - . - -- --- ´
lets learn to count! :) in hex editing files, specially save files (files
that save records of some time), we need to know the length of the various
fields/variables, cause its crucial. when we edit a binary file, we must
not add more bytes to it!!! we only overwrite things in the file, so that
the file size don't change and also wont overlap fields. lets see a small
example...
we have a record like this:
person = record
name : string[30];
phone : string[20];
end;
if we edit the file with a hex editor we will get something like below.
this is not an actual representation.
xqtr..........................123456789...........
now, if we want to change the name or phone to something else, we
overwrite that data and make sure that we don't overlap the fields. for
example:
this is correct:
mamadu........................88888888888888......
but this is not:
my name is not of your bussiness777777777.........
the string we inserted as name, now overlaps and is occuping space in the
field we have for the telephone number. when we execute the program that
uses this file, we will see, that in the area that displays the phone
number will show something like this: ss777777777
so, all variables have a specific size, which we need to know. but how we
know it? simple (?)... we look into our programming language variable
reference. for example the following variables are used in FreePascal:
Byte 1
Shortint 1
Smallint 2
Word 2
Integer 2 or 4
Cardinal 4
Longint 4
Longword 4
Int64 8
QWord 8
each programming language has its own specifications. in hex editing we
don't care if in pascal a variable type is named as integer and in c is
named uint16... we care about the bytes! if those two types occupy the
same size of bytes, we are good to go.
but... (there is always a but... :) there are more complex variable types
than just numbers or strings... in reality, not even strings are so
simple.. :( lets to some string math...
in pascal strings are stored in a different way than other programming
languages. for example a variable like String[10]... it doesn't occupy 10
bytes, as expected in the file, but 11! thats because pascal holds the
size of the string in one byte, before the actual string. for example a
string[10] variable that holds the value "string10" in hex, it shows like
this:
.......0d 0A 73 74 72 69 6e 67 31 30 0a 00 00 00 00 00 .string10......
the first byte "0A" is the actual size of our string. its not something
good or bad... its just the way pascal saves string formats, but its not
compatible with other languages like c. so when we edit a pascal save
file, we have to know it or if we don't know it in advance, be aware that
the save file maybe a pascal type.
lets make a practival example. open the file records.112 from mystic bbs
software and take a look at the records, for example:
RecHistory = Record
Date : LongInt;
Emails : Word;
Posts : Word;
Downloads : Word;
Uploads : Word;
DownloadKB : LongInt;
UploadKB : LongInt;
Calls : LongInt;
NewUsers : Word;
Telnet : Word;
FTP : Word;
POP3 : Word;
SMTP : Word;
NNTP : Word;
HTTP : Word;
Hourly : Array[0..23] of Byte;
Reserved : Array[1..2] of Byte;
End;
lets count, how many bytes ocupies this record in a file:
RecHistory = Record
Date : LongInt; 4
Emails : Word; 2
Posts : Word; 2
Downloads : Word; 2
Uploads : Word; 2
DownloadKB : LongInt; 4
UploadKB : LongInt; 4
Calls : LongInt; 4
NewUsers : Word; 2
Telnet : Word; 2
FTP : Word; 2
POP3 : Word; 2
SMTP : Word; 2
NNTP : Word; 2
HTTP : Word; 2
Hourly : Array[0..23] of Byte; 24
Reserved : Array[1..2] of Byte; 2
End;
Total : 64 bytes
if we devide the size of the record with the file size, we will get how
many records the files stores! which is very useful. or if we know the
record size and how many records we have, we can calculate the file size.
the important thing is, that we edit the file and for example we want to
change the number of email a user has we must put a number that occupies 2
bytes, cause the variable is of type word. you must also have in mind the
endianess of the system, when writing numbers... remember? from previous
tutor?
again from the mystic bbs, records.112 file we have the following field:
OptionData : Array[1..10] of String[60];
can you guess the size? is it 10 x 60 = 600 bytes? not... as we said
pascal saves strings with one more byte, so a string[60] type has a size
of 61 bytes. so the size of the above array is: 10 x 61= 610 bytes.
if you are not 100% sure or too lazy to calculate it by yourself, you can
use a programming language to do it for you. each programming language has
a function that gives the size of a structure/record. in pascal is the
function "sizeof()". you can write a simple program like this:
Program count_zero;
uses sysutils;
type
RecHistory = Record
Date : LongInt;
Emails : Word;
Posts : Word;
Downloads : Word;
Uploads : Word;
DownloadKB : LongInt;
UploadKB : LongInt;
Calls : LongInt;
NewUsers : Word;
Telnet : Word;
FTP : Word;
POP3 : Word;
SMTP : Word;
NNTP : Word;
HTTP : Word;
Hourly : Array[0..23] of Byte;
Reserved : Array[1..2] of Byte;
End;
var
rec : RecHistory;
Begin
WriteLn('Size of record: '+inttostr(sizeof(rec)));
End.
the program will tell us exactly the size of this record/structure.
but why counting bytes/size is important? for various reasons, but i think
the most important is to be able to find the exact position of a field
inside a save file and not looking/changing random numbers. :) specially
in big files.
what if we want to find the number of emails, of the 5th record saved in
the file. we calculate the position like this:
position_in_file = variable_offset + (struct_size * count)
our variable (email) has an offset of 4 and the structure size is 64, so
the position is:
position = 4 + (64 * 5) = 324
test it and see it yourself. now you can find the position of a structure
field and change its value.
+ --- -- - . - --- --- --- - . - -- --- ´
_____ _ _ ____ _ _
| _ |___ ___| |_| |_ ___ ___ | \ ___ ___|_|_| | 8888
| | | . | _| | -_| _| | | | _| . | | . | 8 888888 8
|__|__|_|_|___|_| |_|_|___|_| |____/|_| |___|_|___| 8888888888
8888888888
DoNt Be aNoTHeR DrOiD fOR tHe SySteM 88 8888 88
8888888888
/: HaM RaDiO /: ANSi ARt! /: MySTiC MoDS /: DooRS '88||||88'
/: NeWS /: WeATheR /: FiLEs /: SPooKNet ''8888"'
/: GaMeS /: TeXtFiLeS /: PrEPardNeSS /: FsxNet 88
/: TuTors /: bOOkS/PdFs /: SuRVaViLiSM /: ArakNet 8 8 88888888888
888 8888][][][888
TeLNeT : andr01d.zapto.org:9999 [UTC 11:00 - 20:00] 8 888888##88888
SySoP : xqtr eMAiL: xqtr@gmx.com 8 8888.####.888
DoNaTe : https://paypal.me/xqtr 8 8888##88##888