Converting string to bytes and writing to file in Lua - string

I'm trying to convert and write string data into the file as bytes.
I have already tried something to, but instead of seeing 00 inside hexdump, im seeing 0x30 inside file which is hexadecimal value for character 0.
Here is what I wrote:
local data = "000000010000000100000004000000080000000100000000"
for i=1,#data,2 do
file:write(tonumber(data:sub(i,i+1)))
end
io.close(file)
When I do hexdump of the file I'm getting this:
0000000 30 30 30 31 30 30 30 31 30 30 30 34 30 30 30 38
0000010 30 30 30 31 30 30 30 30
0000018
Expected is:
0000000 00 00 00 01 00 00 00 01 00 00 00 04 00 00 00 08
0000010 00 00 00 01 00 00 00 00
0000018

You want to use string.char in one way:
local data = "000000010000000100000004000000080000000100000000"
for i=1,#data,2 do
file:write(string.char(tonumber(data:sub(i,i+1), 16)))
end
io.close(file)
or another:
local data = string.char(0,0,0,1,0,0,0,1,0,0,0,4,0,0,0,8,0,0,0,1,0,0,0,0)
file:write(data)
io.close(file)
Note that strings in Lua may contain any bytes you want including null bytes. See Values and Types.

Hint: Use string.char to convert numbers to bytes:
file:write(string.char(tonumber(data:sub(i,i+1))))
If the strings contains hexadecimal, use tonumber(...,16).

Related

Recover BMP image header

I am trying to recover some BMP image header, and the all information I got is this:
the bytes of the header that have been deleted are 54
the start offset is 1130 (decimal)
the width is 350 (decimal).
bits per pixel is 8
no compression
So I read little bit (mostly from here) and I saw which bytes present what, and I got the next first 54 bytes of the BMP header:
42 4D 6E 7F 0C 00 00 00 00 00 36 00 00 00 28 00 00 00 F4 01 00 00 22 02 00 00 01 00 18 00 00 00 00 00 38 7F 0C 00 13 0B 00 00 13 0B 00 00 00 00 00 00 00 00 00 00
But for some reason, when I am trying to open my all BMP images and my header, I get just a black image. Did I do something wrong? Do I build the
wrong header from the information above?

How to convert Big Endian Hex to ASCII in Node?

I'm trying to interpret a HEX message that is transmitted in network byte order (big endian), how should I proceed to achieve conversion to ASCII?
server.on('message', function (message, remote) {
//I receive message via UDP in HEX.
});
The message comes in this format:
2B 41 43 4B 19 EF 24 10 01 02 03 02 56 50 22 00 0A 02 3B 01 00 00 4E 07 DD 02 17 11 21 20 46 AD 4E 1E 0D 0A
With that being said, each byte has a parameter attached, let's say I have 4 bytes to parameter1, 2 bytes to parameter2 and 8 bytes to parameter 3, how would I interpret it?

Comparing big files

So I've got really big .bin files with bytes written in them. They have 96-bit numbers written in them as two's complement numbers (still no ASCII, only bytes). Now I have to write an assembly program to sort the numbers in this files and save it to another file (don't ask why, assembly class). I've done it for a file with 32k numbers, like this:
./main < inSort32Kx96b.bin > XD.bin
diff outSort32Kx96b.bin XD.bin
The file outSort32Kx96b.bin is given to me by my teacher. So now diff doesn't output anything, they are identical (I can check that with hexdump or mcview). But I got another file inSort1Kx96b.bin. And I also sort it. But then diff says:
Binary files outSort1Kx96b.bin and XD.bin differ
#Edit:
cmp gave the number of byte where those 2 files differ. Now I can see the difference:
So the difference appears from 0x000017C0. Then I don't know now. If they are written as two's complement numbers in little endian order, then which one is bigger, f.e
00 00 00 00 00 00 00 81 00 00 00 00
or
00 00 00 00 00 00 00 7F 00 00 00 00
?
A hexdump shows you the single bytes in big endian order. If a bunch of bytes have to be interpreted as a number, only the byte order is reversed.
little endian big endian (C notation)
AB CD EF = 0xEFCDAB
01 02 03 04 05 06 07 08 09 10 11 12 = 0x121110090807060504030201
Let's translate your examples to big endian order:
0x000000008100000000000000
0x000000007F00000000000000
You can see that the first number is bigger.
"Two's complement number" is not a very clear expression. Better is "signed integer". The sign which shows whether the number is positive or negativ, is the very first bit of the number. This bit can be found at the begginning of a big endian number and the end of a little endian number.
Positive:
00 00 00 00 00 00 00 81 00 00 00 00 = 0x000000008100000000000000
00 00 00 00 00 00 00 81 00 00 00 10 = 0x100000008100000000000000
00 00 00 00 00 00 00 81 00 00 00 7F = 0x7F0000008100000000000000
Negativ:
00 00 00 00 00 00 00 81 00 00 00 80 = 0x800000008100000000000000
00 00 00 00 00 00 00 81 00 00 00 CD = 0xCD0000008100000000000000
00 00 00 00 00 00 00 81 00 00 00 F0 = 0xF00000008100000000000000

Unable to identify AFL on a smart card

I'm working to get useful data from a VISA (such as PAN, expiry date...) credit card using a list of AIDs I got stuck.
I have been able to access to all the data manually. Using the next tutorial: http://www.openscdp.org/scripts/tutorial/emv/reademv.html
>>00 A4 04 00 07 A0 00 00 00 03 10 10 00
In ASCII:
<<o<EM>„<BEL> <0><0><0><ETX><DLE><DLE>¥<SO>P<EOT>VISA¿<FF><ENQ>ŸM<STX><VT><LF><0>
In Hexadecimal:
<<6F 19 84 07 A0 00 00 00 03 10 10 A5 0E 50 04 56 49 53 41 BF 0C 05 9F 4D 02 0B 0A 90 00
After that I used:
>>33 00 B2 01 0C 00 //sfi1, rec1
...
...
>>33 00 B2 10 FC 00 //sfi31, rec16
I continued with the tutorial and learned that the proper way to obtain the data was using GPO (Get Processing Options) command. And tried that next:
>>80 A8 00 00 0D 83 0B 00 00 00 00 00 00 00 00 00 00 00 00 // pdo = 83 0B 00 00 00 00 00 00 00 00 00 00 00 which suposse to be the correct one for VISA.
<< 69 85
So the condition of use is not satisfied.
>> 80 A8 00 00 02 83 00 00 //pdo= 83 00 that should work with every non visa card
<< 80 0E 3C 00 08 01 01 00 10 01 04 00 18 01 03 01 90 00
If this response is correct and it looks quite well for me as it starts by 80 and ends by 90 00, I am not able to identify AFL which I think that would make me possible to determine the PAN, expiry date... Can somebody help me?
The FCI that you received in response to the select command (00 A4 0400 07 A0000000031010 00) decodes to
6F 19 (File Control Information (FCI) Template)
84 07 (Dedicated File (DF) Name)
A0000000031010
A5 0E (File Control Information (FCI) Proprietary Template)
50 04 (Application Label)
56495341 ("VISA")
BF0C 05 (File Control Information (FCI) Issuer Discretionary Data)
9F4D 02 (Log Entry)
0B0A (SFI = 11; # of records = 10)
This FCI does not include any PDOL (processing options data list). Consequently, you need to assume a default value for the PDOL (which is an empty list for your card type). Consequently, the PDOL-related data field in the GET PROCESSING OPTIONS command must be empty:
83 00
Where 0x83 is the tag for PDOL-related data and 0x00 is a length of zero bytes.
Thus, the correct GPO command is (as you already found out):
80 A8 0000 02 8300 00
You got the response
800E3C00080101001001040018010301 9000
This decodes to
80 0E (Response Message Template Format 1)
3C00 (Application Interchange Profile)
08010100 10010400 18010301 (Application File Locator)
Consequently, the Application File Locator contains the following three entries:
08010100: SFI = 1, first record = 1, last record = 1, records involved in offline data authentication = 0
10010400: SFI = 2, first record = 1, last record = 4, records involved in offline data authentication = 0
18010301: SFI = 3, first record = 1, last record = 3, records involved in offline data authentication = 1
Consequently, you can read those record with the READ RECORD commands:
00 B2 010C 00
00 B2 0114 00
00 B2 0214 00
00 B2 0314 00
00 B2 0414 00
00 B2 011C 00
00 B2 021C 00
00 B2 031C 00

How to get the offset in a block device of an inode in a deleted partition

During a fresh installation, I accidentally formatted a disk containing datas. I have tried using some tools: testdisk, foremost, but I did not get good results. (see my unsuccessful post on superuser).
So I have decided to read some docs about ext2 filesystem structure, and I could get some results:
The deleted partition have a directory tree like that:
dev
|-scripts
|-projects
|-services
|-...
Medias
|-downloads
|-Musique
|-...
backup
...
So, based on the ext2 directory entry format:
Directory Entry
Starting_Byte Ending_Byte Size_in_Bytes Field_Description
0 3 4 Inode
4 5 2 Total size of this entry (Including all subfields)
6 6 1 Name Length least-significant 8 bits
7 7 1 Type indicator (only if the feature bit for "directory entries have file type byte" is set, else this is the most-significant 8 bits of the Name Length)
8 8+N-1 N Name characters
I tried to find some datas matching this structure.
I used this script:
var bindexOf = require('buffer-indexof');
var currentOffset=0;
var deviceReadStream = fs.createReadStream("/dev/sdb");
deviceReadStream.on('error',function(err){
console.log(err);
});
deviceReadStream.on('data',function(data){
var dirs = ["dev","scripts","services","projects","Medias","downloads","Musique","backup"];
dirs.forEach(function(dir){
dirOctetFormat = new Buffer(2);
dirOctetFormat.writeUInt8(dir.length,0);
dirOctetFormat.writeUInt8(2,1);// type is directory
dirOctetFormat= Buffer.concat( [dirOctetFormat, new Buffer(dir)]);
var offset = bindexOf( data, dirOctetFormat );
if( offset >= 0 ){
console.log( dir + " entry found at offset " + (currentOffset + offset) );
}
});
currentOffset += data.length;
});
}
I found data which seems to be the directory entry of the dev directory:
===== Current offset: 233590226944 - 217.5478515625Gio ======
scripts entry found at offset 233590227030
services entry found at offset 233590227014
projects entry found at offset 233590228106
If it is the case, I got the inode numbers of its children directories: scripts, projects, services,...
But I do not know what to do with that!
I tried to deduce the location of these inodes, based on this guide,
but as I was unable to find a superblock of the deleted filesystem, I just have to make guesses about the block size, the number of blocks, ...
and that seems a little bit fuzzy to me to hope obtaining a result.
So could you have some intervals for all values needed to obtain the offset of an inode, and a more formal formula to get this offset?
If you have only erased the partition table (or modified it) you can still get your data, if data has not been reused for something else.
ext2 filesystems have a MAGIC number in superblock, so to recover your partition you have only to search for it. I did this on one machine and was able to recover not one, but seven partitions in one disk. You have some chances to get invalid numbers, but just search for that magic. Magic number is defined in include/uapi/linux/magic.h and value is #define EXT2_SUPER_MAGIC 0xEF53 (it's found at offset #define EXT2_SB_MAGIC_OFFSET 0x38 ---from file include/linux/ext2_fs.h)
To search for the superblock, just try to find 0xef53 at offset 0x38 in one sector of the disk, it will mark the first block of the partition. Be careful, that superblock is replicated several times in one partition, so you'll find all the copies of it.
Good luck! (I had when it happened to me)
Edit (To illustrate with an example)
Just see the magic number in one of my own partitions:
# hd /dev/sda3 | head -20
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000400 40 62 08 00 00 87 21 00 26 ad 01 00 f6 30 15 00 |#b....!.&....0..|
00000410 1d 31 08 00 00 00 00 00 02 00 00 00 02 00 00 00 |.1..............|
00000420 00 80 00 00 00 80 00 00 90 1f 00 00 cf 60 af 55 |.............`.U|
00000430 fc 8a af 55 2d 00 ff ff 53 ef 01 00 01 00 00 00 |...U-...S.......|<- HERE!!!
00000440 36 38 9d 55 00 00 00 00 00 00 00 00 01 00 00 00 |68.U............|
00000450 00 00 00 00 0b 00 00 00 00 01 00 00 3c 00 00 00 |............<...|
00000460 46 02 00 00 7b 00 00 00 5a bf 87 15 12 8f 44 3b |F...{...Z.....D;|
00000470 97 e7 f3 74 4d 75 69 12 72 6f 6f 74 00 00 00 00 |...tMui.root....|
00000480 00 00 00 00 00 00 00 00 2f 00 61 72 67 65 74 00 |......../.arget.|
00000490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18 02 |................|
000004d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000004e0 08 00 00 00 00 00 00 00 00 00 00 00 93 54 99 ab |.............T..|
000004f0 aa 64 46 b3 a6 73 94 34 a3 79 46 28 01 01 00 00 |.dF..s.4.yF(....|
00000500 0c 00 00 00 00 00 00 00 e5 61 92 55 0a f3 02 00 |.........a.U....|
00000510 04 00 00 00 00 00 00 00 00 00 00 00 ff 7f 00 00 |................|
00000520 00 80 10 00 ff 7f 00 00 01 00 00 00 ff ff 10 00 |................|
Remember it is on offset 0x38 counted from the block origin, and assume the super block is the second block (block 0 reserved for bootcode, so it will be block 1, with two sectors per block, to make 1k blocksize) in the partition, so you'll have to rewind 0x438 bytes from the beginning of the magic number to get the partition origin.
I have run the command on my whole disk, getting the following result:
# hd /dev/sda | grep " [0-9a-f][0-9a-f] 53 ef" | sed -e 's/^/ /' | head
006f05f0 ee 00 00 11 66 0a 00 00 53 ef 00 00 11 66 2d 00 |....f...S....f-.|
007c21d0 55 2a aa 7d f4 aa 89 55 53 ef a4 91 70 40 c1 00 |U*.}...US...p#..|
20100430 fc 8a af 55 2d 00 ff ff 53 ef 01 00 01 00 00 00 |...U-...S.......|
2289a910 0f 8f 4f 03 00 00 81 fe 53 ef 00 00 0f 84 ce 04 |..O.....S.......|
230d4c70 0a 00 00 00 1c 00 00 00 53 ef 01 00 00 00 00 00 |........S.......|
231b7e50 a0 73 07 00 00 00 00 00 53 ef 0d 00 00 00 00 00 |.s......S.......|
23dbd230 d5 08 ad 2b ee 71 07 8a 53 ef c2 89 d4 bb 09 1f |...+.q..S.......|
25c0c9e0 06 00 00 00 00 4f 59 c0 53 ef 32 c0 0e 00 00 00 |.....OY.S.2.....|
25d72ca0 b0 b4 7b 3d a4 f7 84 3b 53 ef ba 3c 1f 32 b9 3c |..{=...;S..<.2.<|
25f0eab0 f1 fd 02 be 28 59 67 3c 53 ef 9c bd 04 30 72 bd |....(Yg<S....0r.|
Clearly, there are much more uninteresting lines in this listing than the ones we need. To locate the one interesting here, we have to do some computing with the numbers. We have seen that sectors are 512 bytes long (this is 0x200 in hex) and we can have the superblock magic at offset 0x438, so we expect valid offsets to be at 0xXXXXXX[02468ace]38 only. Just select the lines with offsets ending in that expression, and you'll get the first superblock valid (in the third line) at offset 0x20100430.
Substract 0x430 to give the byte offset of the partition (0x20100000, and then, divide the result by 0x200, giving 0x100800, or 1050624)
# fdisk -l /dev/sda | sed -e 's/^/ /'
Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: DF97DAD4-727D-4BB3-BD7B-3C5A584A2747
Device Start End Sectors Size Type
/dev/sda1 2048 526335 524288 256M EFI System
/dev/sda2 526336 1050623 524288 256M BIOS boot
/dev/sda3 1050624 18628607 17577984 8.4G Linux filesystem <-- HERE!!!
/dev/sda4 18628608 77221887 58593280 28G Linux filesystem
/dev/sda5 77221888 85035007 7813120 3.7G Linux filesystem
/dev/sda6 85035008 104566783 19531776 9.3G Linux filesystem
/dev/sda7 104566784 135817215 31250432 14.9G Linux swap
/dev/sda8 135817216 155348991 19531776 9.3G Linux filesystem
/dev/sda9 155348992 1953523711 1798174720 857.4G Linux filesystem

Resources