I was doing some random experiments using assembly and C. This is a simple example in packing 2 numbers inside a register in assembly. Let’s assume
$latex al < 2^{5}&bg=232225&fg=bbbbbb&s=4$
$latex bl < 2^{3}&bg=232225&fg=bbbbbb&s=4$
We want to store these 2 values inside the dl register. The dl register is of 8 bits, so 5 + 3 = 8 bits
Packing
1 2 3 4 |
; al < 2 ^ 5, bl < 2 ^ 3 mov al, bl shl dl, 3 or dl, bl ; xor would also work fine |
Unpacking
1 2 3 4 5 |
mov cl, dl ; Make a copy of dl and dl, 111b ; Extract lowest 3 bits (b) mov bl, dl shr cl, 3 ; Extract highest 5 bits (a) mov al, cl |
After experimenting with this I thought of coding a high level version of this using C. In here we pack and unpack a DWORD and a short inside a DWORD64 variable and build a string value and again unpack the DWORD64 value back to their original variables with the original values.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#include <stdio.h> #include <windows.h> /* * Author : @OsandaMalith * Website: https://osandamalith.com * Description: Simple experiment of packing and unpacking a DWORD and a short inside a DWORD64 variable and making a string value. */ int main() { DWORD a = 1633971809; // a < 2 ^ 32 short b = 29519; // b < 2 ^ 16; DWORD64 pack = 0, temp = 0; printf("Value of a = %d\n",a); printf("Value of b = %d\n\n",b); puts("\t-=[Packing]=-\n"); pack = a; pack <<= 0x10; // shift 2 bytes left pack |= b; printf("Packed data: 0x%I64X\n\n",pack); printf("As a string: %s\n\n",&pack); // clear the variables a ^= a; b ^= b; puts("\t-=[Unpacking]=-\n"); temp = pack; pack &= 0xffff; // Extract the lowest 16 bits b = pack; temp >>= 0x10; // Extract the highest 32 bits a = temp; printf("Value of a = %d\n",a); printf("Value of b = %d\n\n",b); return 0; } |