Skip to content

Instantly share code, notes, and snippets.

@lighth7015
Created March 21, 2019 20:14
Show Gist options
  • Save lighth7015/ad90db974e15dc40e018bf2c3d14c0fd to your computer and use it in GitHub Desktop.
Save lighth7015/ad90db974e15dc40e018bf2c3d14c0fd to your computer and use it in GitHub Desktop.
AOL packet parser
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
const uint8_t* packet = (const uint8_t *)
"5A413800347F7FA3036B0100F5000000050F00002152CBCA070A1000080400000000035F0000010004000300080000000000000000000000020D";
#ifndef NDEBUG
void g_log_write_event(const char *fmt, const char* filename, const char* source, int line, ...)
{
va_list args;
va_start(args, line);
char *entry;
vasprintf(&entry, fmt, args);
printf("%s[%d] %-16s: %s\n", filename, line, source, entry);
va_end(args);
free(entry);
}
#define g_write_log(format, ...) \
g_log_write_event(format, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define g_write_log(format, ...)
#endif
typedef
struct Header
{
uint8_t magic; /* always 0x5a */
uint16_t checksum; /* a simple CRC16 on the packet
not including magic */
uint16_t size; /* total size of the packet from next byte,
* not including the stop byte
*/
uint8_t seq;
uint8_t ack;
#if WORDS_BIGENDIAN
uint8_t client:1; /* this bit is always set for client */
uint8_t type:7; /* see below */
#else
uint8_t type:7; /* see below */
uint8_t client:1; /* this is always set for client */
#endif
}
__attribute__ ((packed)) *protocol_header_t;
typedef struct
Packet {
uint8_t magic; /* 0x03 for windows , 0x0c for Mac */
uint8_t version; /* see above */
uint8_t subversion;
uint8_t unused;
uint8_t machinemem; /* unused alway 0 */
uint8_t appmem; /* unused always 16 */
uint16_t pctype; /* unused always 0 */
uint8_t release_month; /* unused alway 5 */
uint8_t release_day; /* unused alway 15 */
uint16_t customer_class; /* unused always 0 */
uint32_t timestamp; /* timestamp of the version */
uint16_t dosversion;
uint16_t flags; /* curently don't know what they are for */
uint8_t video;
uint8_t processor;
uint32_t media;
uint32_t winversion;
uint8_t winmode; /* an old remanant field ;) alaways 1 */
uint16_t xres;
uint16_t yres;
uint16_t nbcolors; /* for 16&24 bits depth: 0xffff */
uint8_t filler; /* unused alway 0 */
uint16_t region; /* it seems always 0 */
uint16_t languages[4];
uint8_t speed; /* don't know how it is coded */
}
__attribute__ ((packed)) *protocol_packet_t;
uint16_t
CompCRC16( const unsigned char *buffer, size_t num_bytes )
{
unsigned char i;
unsigned int data, crc = 0xffff;
if (num_bytes == 0)
return (~crc);
do {
for ( i=0, data=(unsigned int)0xff & *buffer++
; i < 8
; i++, data >>= 1)
{
if ((crc & 0x0001) ^ (data & 0x0001))
crc = (crc >> 1) ^ 0x8408;
else crc >>= 1;
}
} while (--num_bytes);
crc =~ crc;
data = crc;
return (crc << 8) | (data >> 8 & 0xff);
}
void hexdump(void *addr, char *desc, int len)
{
unsigned char buff[17];
unsigned char *pc = (unsigned char*)addr;
int i = 0;
// Output description if given.
if (desc != NULL)
printf ("%s:\n", desc);
// Process every byte in the data.
for (; i < len; i++) {
// Multiple of 16 means new line (with line offset).
if ((i % 16) == 0) {
// Just don't print ASCII for the zeroth line.
if (i != 0)
printf(" %s\n", buff);
// Output the offset.
printf(" %04x ", i);
}
// Now the hex code for the specific character.
printf(" %02x", pc[i]);
// And store a printable ASCII character for later.
if ((pc[i] < 0x20) || (pc[i] > 0x7e)) {
buff[i % 16] = '.';
} else {
buff[i % 16] = pc[i];
}
buff[(i % 16) + 1] = '\0';
}
// Pad out last line if not exactly 16 characters.
while ((i % 16) != 0) {
printf(" ");
i++;
}
// And print the final ASCII bit.
printf(" %s\n", buff);
}
int decode_hex(char c)
{
int first = c / 16 - 3;
int second = c % 16;
int result = first * 10 +
second;
if(result > 9)
result--;
return result;
}
char decode_str(char c, char d)
{
return (decode_hex(c) * 16 +
decode_hex(d));
}
int main(){
const char* st = (const char*) packet;
const uint32_t nbytes = strlen(st) / 2;
char* buffer = calloc(nbytes, sizeof(char));
for(uint32_t c = packet[0], p = 0, i = 0; i < strlen(st) / 2; i++, c = packet[i])
{
if (i % 2 != 0) {
buffer[i / 2] = decode_str( p, st[i]);
}
else {
p = c;
}
}
size_t hdrlen = sizeof(struct Header),
offset = nbytes - sizeof(struct Header);
size_t length = nbytes - hdrlen;
protocol_header_t h = (protocol_header_t) buffer;
protocol_packet_t p = (protocol_packet_t) (buffer + hdrlen);
printf( "\n" );
hexdump((void *) h, "Packet header", hdrlen);
printf( "\n" );
hexdump((void *) p, "Packet content", length);
printf( "\n" );
printf( "Packet info:\n" );
printf( "\n" );
g_write_log( "Request %-24s: %X, %x [%x + %x]", "magic/checksum",
h->magic, h->checksum, CompCRC16( (uint8_t *) buffer + offset, length),
CompCRC16( (uint8_t *) p, length ));
/*
g_write_log( "Machine %-24s: (%d, %d)", "resolution", p->xres, p->yres );
g_write_log( "Machine %-24s: %d", "app memory", p->appmem );
g_write_log( "Machine %-24s: %d", "video mode", p->video );
g_write_log( "Machine %-24s: %x", "OS version", p->winversion );
*/
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment