Created
November 12, 2018 07:09
-
-
Save bongtrop/2b222dfdecec4437d8fb8b05d12fbfa3 to your computer and use it in GitHub Desktop.
memory_cache reversed
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int __cdecl main(int argc, const char **argv, const char **envp) | |
{ | |
__int64 buf_len; // rax | |
int cmd; // [rsp+4h] [rbp-2Ch] | |
char *buf; // [rsp+8h] [rbp-28h] | |
char hash_buf; // [rsp+10h] [rbp-20h] | |
unsigned __int64 v8; // [rsp+28h] [rbp-8h] | |
v8 = __readfsqword(0x28u); | |
dprintf(1, "Starting MemoryCache...\n", envp); | |
while ( 1 ) | |
{ | |
cmd = get_command(&buf); | |
if ( !cmd ) | |
break; | |
if ( buf ) | |
{ | |
buf_len = strlen(buf); | |
sha1sum((__int64)&hash_buf, (__int64)buf, buf_len); | |
free(buf); | |
if ( cmd == 1 ) | |
{ | |
set(&hash_buf); | |
} | |
else if ( cmd == 2 ) | |
{ | |
get((__int64)&hash_buf); | |
} | |
else | |
{ | |
dprintf(1, "Invalid Command\n"); | |
} | |
} | |
else | |
{ | |
dprintf(1, "Syntax Error\n"); | |
} | |
} | |
return 0; | |
} | |
unsigned __int64 __fastcall sha1sum(__int64 a1, __int64 a2, __int64 a3) | |
{ | |
__int64 v3; // ST08_8 | |
char v5; // [rsp+20h] [rbp-70h] | |
unsigned __int64 v6; // [rsp+88h] [rbp-8h] | |
v3 = a3; | |
v6 = __readfsqword(0x28u); | |
SHA1_Init(&v5); | |
SHA1_Update(&v5, a2, v3); | |
SHA1_Final(a1, &v5); | |
return __readfsqword(0x28u) ^ v6; | |
} | |
signed __int64 __fastcall get_command(char **inbuf) | |
{ | |
unsigned int status; // [rsp+14h] [rbp-11Ch] | |
char *sptr; // [rsp+18h] [rbp-118h] | |
char buf[256]; // [rsp+20h] [rbp-110h] | |
unsigned __int64 v5; // [rsp+128h] [rbp-8h] | |
v5 = __readfsqword(0x28u); | |
memset(buf, 0, sizeof(buf)); | |
status = 3; | |
*inbuf = 0LL; | |
if ( read(0, buf, 255uLL) <= 0 ) | |
return 0LL; | |
if ( !strncasecmp("EXIT", buf, 4uLL) ) | |
return 0LL; | |
sptr = strchr(buf, ' '); | |
if ( !sptr ) | |
return 3LL; | |
if ( !strncasecmp("SET", buf, sptr - buf) ) | |
{ | |
status = 1; | |
} | |
else if ( !strncasecmp("GET", buf, sptr - buf) ) | |
{ | |
status = 2; | |
} | |
*inbuf = strdup(sptr + 1); | |
return status; | |
} | |
btree_node *__fastcall find_entry(const void *hash_buf) | |
{ | |
int cmp_flag; // [rsp+14h] [rbp-Ch] | |
btree_node *ptr; // [rsp+18h] [rbp-8h] | |
ptr = top; | |
while ( ptr ) | |
{ | |
cmp_flag = memcmp(hash_buf, ptr, 20uLL); | |
if ( cmp_flag >= 0 ) | |
{ | |
if ( cmp_flag <= 0 ) | |
return ptr; | |
ptr = ptr->right; | |
} | |
else | |
{ | |
ptr = ptr->left; | |
} | |
} | |
return 0LL; | |
} | |
ssize_t __fastcall get(__int64 hash_buf) | |
{ | |
btree_node *ent; // [rsp+18h] [rbp-8h] | |
ent = find_entry((const void *)hash_buf); | |
if ( !ent ) | |
return write(1, "0, \n", 4uLL); | |
dprintf(1, "%zd, ", ent->data_size); | |
write(1, ent->data_ptr, ent->data_size); | |
return write(1, "\n", 1uLL); | |
} | |
unsigned __int64 __fastcall set(const void *hash_buf) | |
{ | |
unsigned __int64 n; // rax | |
int i; // eax | |
btree_node *dest; // [rsp+18h] [rbp-138h] | |
btree_node *ptr; // [rsp+20h] [rbp-130h] | |
size_t size; // [rsp+28h] [rbp-128h] | |
unsigned __int64 csize; // [rsp+30h] [rbp-120h] | |
char *nbuf; // [rsp+38h] [rbp-118h] | |
char buf; // [rsp+40h] [rbp-110h] | |
unsigned __int64 v10; // [rsp+148h] [rbp-8h] | |
v10 = __readfsqword(0x28u); | |
memset(&buf, 0, 256uLL); | |
if ( read(0, &buf, 255uLL) <= 0 ) | |
n = 0LL; | |
else | |
n = atoi(&buf); | |
size = n; | |
if ( (n & 0x80000000) == 0LL && n <= 0x400 ) | |
{ | |
dest = find_entry(hash_buf); | |
if ( dest ) | |
{ | |
csize = *((_QWORD *)dest->data_ptr - 1) - 8LL; | |
if ( csize > 0x3FF ) | |
__assert_fail("(usable = malloc_usable_size(entry->data)) < 0x400", "memory_cache.c", 0x64u, "set"); | |
if ( csize < size ) | |
{ | |
nbuf = (char *)realloc(dest->data_ptr, size);// free | |
if ( !nbuf ) | |
{ | |
dprintf(1, "NG %zd\n", size); | |
return __readfsqword(0x28u) ^ v10; | |
} | |
dest->data_ptr = nbuf; | |
} | |
} | |
else | |
{ | |
dest = (btree_node *)realloc(0LL, 0x38uLL); | |
if ( !dest ) | |
return __readfsqword(0x28u) ^ v10; | |
memcpy(dest, hash_buf, 20uLL); | |
dest->data_ptr = (char *)realloc(0LL, size); | |
if ( !dest->data_ptr ) | |
{ | |
free(dest); | |
dprintf(1, "NG %zd\n", size); | |
return __readfsqword(0x28u) ^ v10; | |
} | |
dest->right = 0LL; | |
dest->left = dest->right; | |
if ( top ) | |
{ | |
ptr = top; | |
LABEL_20: | |
for ( i = memcmp(hash_buf, ptr, 20uLL); ; i = memcmp(hash_buf, ptr, 20uLL) ) | |
{ | |
while ( 1 ) | |
{ | |
if ( !i ) | |
__assert_fail("cmp != 0", "memory_cache.c", 0x88u, "set"); | |
if ( i >= 0 ) | |
break; | |
if ( !ptr->left ) | |
{ | |
ptr->left = dest; | |
goto LABEL_31; | |
} | |
ptr = ptr->left; | |
i = memcmp(hash_buf, ptr, 20uLL); | |
} | |
if ( i <= 0 ) | |
goto LABEL_20; | |
if ( !ptr->right ) | |
break; | |
ptr = ptr->right; | |
} | |
ptr->right = dest; | |
} | |
else | |
{ | |
top = dest; | |
} | |
} | |
LABEL_31: | |
dest->data_size = read(0, dest->data_ptr, size); | |
write(1, "OK\n", 3uLL); | |
return __readfsqword(0x28u) ^ v10; | |
} | |
dprintf(1, "NG %zd\n", n); | |
return __readfsqword(0x28u) ^ v10; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment