Skip to content

Instantly share code, notes, and snippets.

@shuffle2
Last active June 1, 2017 05:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shuffle2/6f443352dbc09bcfe264faea1fc052aa to your computer and use it in GitHub Desktop.
Save shuffle2/6f443352dbc09bcfe264faea1fc052aa to your computer and use it in GitHub Desktop.
IOS59 SO getaddrinfo
/*
00000000
00000000 iov struc ; (sizeof=0x8, mappedto_25)
00000000 ptr DCD ?
00000004 len DCD ?
00000008 iov ends
00000008
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 so_hints struc ; (sizeof=0x20, mappedto_27)
00000000 ai_flags DCD ?
00000004 ai_family DCD ?
00000008 ai_socktype DCD ?
0000000C ai_protocol DCD ?
00000010 ai_addrlen DCD ?
00000014 DCB ? ; undefined
00000015 DCB ? ; undefined
00000016 DCB ? ; undefined
00000017 DCB ? ; undefined
00000018 DCB ? ; undefined
00000019 DCB ? ; undefined
0000001A DCB ? ; undefined
0000001B DCB ? ; undefined
0000001C DCB ? ; undefined
0000001D DCB ? ; undefined
0000001E DCB ? ; undefined
0000001F field_1F DCB ?
00000020 so_hints ends
00000020
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 SOAddrInfo struc ; (sizeof=0x20, align=0x4, copyof_26)
00000000 flags DCD ?
00000004 family DCD ?
00000008 sockType DCD ?
0000000C protocol DCD ?
00000010 addrLen DCD ?
00000014 canonName DCD ? ; offset
00000018 addr DCD ? ; offset
0000001C next DCD ? ; offset
00000020 SOAddrInfo ends
00000020
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 struct_a4 struc ; (sizeof=0x3C, align=0x4, mappedto_28)
00000000 ; XREF: resolve_addr_info/r
00000000 info DCD ? ; offset
00000004 task_ptr1 DCD ? ; offset
00000008 field_8 DCD ?
0000000C dwordC DCD ?
00000010 callback_0 DCD ? ; offset
00000014 callback_1 DCD ? ; offset
00000018 p_rv DCD ? ; offset
0000001C node_name DCD ? ; offset
00000020 serv_name DCD ? ; offset
00000024 hints DCD ? ; offset
00000028 socktype DCD ? ; XREF: resolve_addr_info+BE/r
0000002C serv_num DCW ? ; XREF: resolve_addr_info+108/o
0000002C ; resolve_addr_info+17A/o ...
0000002E word2E DCW ?
00000030 node_net DCD ? ; offset
00000034 node_canon_name DCD ? ; XREF: resolve_addr_info:loc_13B537B8/r
00000034 ; resolve_addr_info+84/w ... ; offset
00000038 callback_user DCD ? ; offset
0000003C struct_a4 ends
0000003C
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 in_addr6 struc ; (sizeof=0x1C, align=0x2, mappedto_30)
00000000 len DCB ?
00000001 family DCB ?
00000002 port DCW ?
00000004 _pad4 DCD ?
00000008 addr DCB 16 dup(?)
00000018 _pad18 DCD ?
0000001C in_addr6 ends
0000001C
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 in_addr4 struc ; (sizeof=0x8, align=0x2, mappedto_29)
00000000 len DCB ?
00000001 family DCB ?
00000002 port DCW ?
00000004 addr DCB 4 dup(?)
00000008 in_addr4 ends
00000008
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 struct_a1 struc ; (sizeof=0x3374, align=0x4, mappedto_31)
00000000 dword0 DCD ?
00000004 gap4 DCB 7544 dup(?)
00001D7C dword1D7C DCD ?
00001D80 gap1D80 DCB 36 dup(?)
00001DA4 dword1DA4 DCD ?
00001DA8 word1DA8 DCW ?
00001DAA DCB ? ; undefined
00001DAB DCB ? ; undefined
00001DAC word1DAC DCW ?
00001DAE gap1DAE DCB 5550 dup(?)
0000335C cur_task DCD ? ; offset
00003360 task_ptr DCD ? ; offset
00003364 pstruct_a43364 DCD ? ; offset
00003368 gap3368 DCB 8 dup(?)
00003370 dword3370 DCD ?
00003374 struct_a1 ends
00003374
*/
signed int __fastcall get_addr_info_cb_0(struct_a1 *info, struct_a4 *cmd)
{
const char *node_name; // r0@1
signed int v5; // r12@1
_DWORD *v6; // r11@1
int v7; // r2@3
_BYTE *v8; // r1@3
char *v9; // r5@3
int v10; // r3@5
_BYTE *v11; // r6@5
signed int v12; // r4@5
_BYTE *v13; // r1@15
int v14; // r0@15
signed int result; // r0@18
__int16 v16; // [sp+2h] [bp-26h]@1
node_name = cmd->node_name;
v16 = cmd->word2E;
*(_WORD *)&info->gap1DAE[0] = 0;
v5 = 0;
v6 = &info->dword1DA4;
if ( !(info->dword1DA4 & 3) )
*(_WORD *)&info->gap1DAE[0] = 256;
*(_WORD *)&info->gap1DAE[4] = 0;
*(_WORD *)&info->gap1DAE[6] = 0;
*(_WORD *)&info->gap1DAE[8] = 0;
*(_WORD *)&info->gap1DAE[2] = 1;
LOBYTE(v7) = *node_name;
v8 = &info->gap1DAE[10];
v9 = &info->gap1DAE[10];
if ( *node_name )
{
while ( v8 - v9 <= 253 )
{
v10 = (unsigned __int8)v7;
v11 = v8;
v12 = 0;
++v8;
if ( (_BYTE)v7 )
{
while ( v10 != '.' )
{
if ( v12 > 62 || v8 - v9 > 253 )
goto LABEL_21;
*v8 = v7;
LOBYTE(v7) = *++node_name;
v10 = *(unsigned __int8 *)node_name;
++v8;
++v12;
if ( !*node_name )
break;
}
}
*v11 = v12;
v7 = *(unsigned __int8 *)node_name;
if ( v7 == '.' )
{
v7 = *(unsigned __int8 *)++node_name;
v5 = 1;
}
else if ( !v5 && byte_13C3D154 )
{
v5 = 1;
v7 = (unsigned __int8)byte_13C3D154;
node_name = &byte_13C3D154;
}
if ( !(v7 << 24) )
goto LABEL_15;
}
LABEL_21:
result = -12;
}
else
{
LABEL_15:
*v8 = 0;
v13 = v8 + 1;
*v13++ = HIBYTE(v16);
*v13++ = v16;
*v13++ = 0;
*v13++ = 1;
LOWORD(v14) = (_WORD)v13 - (_WORD)info;
*(_DWORD *)&info->gap1DAE[1434] = v13 - (_BYTE *)info - 7596;
if ( *v6 & 0x20 )
{
if ( !((*v6 >> 4) & 1) )
v14 = sub_13B52BB4(&info->word1DAC) - (_DWORD)info;
}
*(&info->word1DA8 + 1) = v14 - 7596;
*(_DWORD *)&info->gap1DAE[5542] = cmd->node_net;
*(_DWORD *)&info->gap1DAE[5546] = 0;
result = 0;
}
return result;
}
void __fastcall get_addr_info_cb_1(struct_a4 *cmd, int rc)
{
struct_a1 *v4; // r5@3
signed int *v5; // r2@3
int v6; // r11@3
unsigned int v7; // r7@10
_BYTE *v8; // r0@10
unsigned int v9; // r10@10
signed int i; // r6@10
signed int *v11; // r3@14
void (__fastcall *v12)(struct_a1 *, int); // r3@16
_BYTE *v13; // r4@19
signed int v14; // r6@19
unsigned __int8 *v15; // r0@21
int v16; // r5@21
int v17; // r2@21
unsigned __int8 *v18; // r4@21
int v19; // r5@24
char *v20; // r12@34
_DWORD *v21; // [sp+4h] [bp-30h]@20
_DWORD *v22; // [sp+8h] [bp-2Ch]@20
void **v23; // [sp+Ch] [bp-28h]@20
if ( !cmd )
sub_13B5ACC0("IPDns.c", 2511, "assert cmd");
v4 = cmd->info;
v5 = cmd->p_rv;
v6 = (unsigned __int16)cmd->word2E;
if ( v5 )
*v5 = -1;
if ( rc >= 0 )
{
if ( !v4 )
sub_13B5ACC0("IPDns.c", 2524, "assert info");
*(_WORD *)&v4->gap1DAE[0] = 0;
if ( !(v4->dword1DA4 & 3) )
*(_WORD *)&v4->gap1DAE[0] = 256;
*(_WORD *)&v4->gap1DAE[2] = 1;
*(_WORD *)&v4->gap1DAE[4] = 0;
*(_WORD *)&v4->gap1DAE[6] = 0;
*(_WORD *)&v4->gap1DAE[8] = 0;
v7 = (unsigned int)&v4->gap1DAE[1442];
v8 = &v4->gap1DAE[1454];
v9 = (unsigned int)&v4->gap1DAE[rc + 1442];
for ( i = 0;
*(unsigned __int16 *)&v4->gap1DAE[1446] > i;
v8 = (_BYTE *)(sub_13B51B64(v8, (unsigned int)&v4->gap1DAE[rc + 1442]) + 4) )
{
++i;
}
if ( v6 == 1 || v6 == 28 )
{
rc = 0;
v13 = v8;
v14 = 0;
if ( (signed int)*(unsigned __int16 *)&v4->gap1DAE[1448] > 0 )
{
v22 = &v4->gap1DAE[5546];
v23 = (void **)&v4->gap1DAE[5542];
v21 = &v4->gap1DAE[5546];
do
{
v15 = (unsigned __int8 *)sub_13B51B64(v13, v9);
v16 = v15[9] | (v15[8] << 8);
v17 = (*v15 << 8) | v15[1];
v18 = v15;
if ( v17 == 5 )
{
v20 = cmd->node_canon_name;
if ( v20 )
{
v19 = (int)&v15[v16];
sub_13B51BA0(v7, v19 + 10, v15 + 10, v20, 256);
goto LABEL_25;
}
}
else if ( v17 > 5 )
{
if ( v17 == 28 && v6 == 28 && *v21 <= 127 )
{
memcpy_1(*v23, v15 + 10, 0x10u);
*v23 = (char *)*v23 + 16;
*v21 += 16;
rc += 16;
}
}
else if ( v17 == 1 && v6 == 1 && *v22 <= 139 )
{
memcpy_1(*v23, v15 + 10, 4u);
*v23 = (char *)*v23 + 4;
*v22 += 4;
rc += 4;
}
v19 = (int)&v18[v16];
LABEL_25:
++v14;
v13 = (_BYTE *)(v19 + 10);
}
while ( *(unsigned __int16 *)(v7 + 6) > v14 );
}
}
}
v11 = cmd->p_rv;
if ( v11 )
*v11 = rc;
v12 = cmd->callback_user;
if ( v12 )
v12(cmd->info, rc);
}
signed int __fastcall start_addr_info_task(const char *node, char *serv, so_hints *hints, struct_a4 *task, void *node_net, void (__fastcall *fptr)(struct_a1 *, int), signed int *p_rv)
{
signed int rv; // r6@1
signed int v11; // r9@1
signed int ai_socktype_; // r10@1
int ai_family; // r0@3
int ai_socktype; // r3@10
int ai_protocol; // r3@14
int ai_flags; // r3@24
signed int pton_needs_space; // r11@28
int v20; // r3@44
int v21; // r3@48
char *v22; // r0@52
int v23; // r3@68
unsigned int v24; // r0@72
signed int has_serv; // [sp+0h] [bp-2Ch]@20
signed int has_node; // [sp+4h] [bp-28h]@17
rv = 0;
v11 = 0;
ai_socktype_ = 0;
task->node_canon_name = 0;
if ( !hints )
sub_13B5ACC0("IPDns.c", 2867, "assert hints");
ai_family = hints->ai_family;
if ( ai_family == 2 || ai_family == 23 )
{
ai_socktype = hints->ai_socktype;
if ( ai_socktype )
{
if ( ai_socktype < 0 || ai_socktype > 2 )
goto LABEL_39;
ai_socktype_ = hints->ai_socktype;
}
ai_protocol = hints->ai_protocol;
if ( ai_protocol == 6 )
{
ai_socktype_ = 1;
goto LABEL_17;
}
if ( ai_protocol > 6 )
{
if ( ai_protocol == 17 )
{
ai_socktype_ = 2;
goto LABEL_17;
}
}
else if ( !ai_protocol )
{
LABEL_17:
has_node = 0;
if ( node && *node )
has_node = 1;
has_serv = 0;
if ( serv && *serv )
has_serv = 1;
if ( has_node )
{
if ( strlen(node) > 0xFF )
goto LABEL_40;
ai_family = hints->ai_family;
}
else
{
ai_flags = hints->ai_flags;
if ( hints->ai_flags & 4 )
goto LABEL_40;
if ( ai_family == 2 )
{
if ( ai_flags & 1 )
node = "0.0.0.0";
else
node = "127.0.0.1";
}
else if ( ai_family == 23 )
{
if ( ai_flags & 1 )
node = "::";
else
node = "::1";
}
}
if ( inet_pton(ai_family, node, node_net) == 1 )
{
v20 = hints->ai_family;
pton_needs_space = 1;
if ( v20 == 2 )
{
rv = 4;
}
else if ( v20 == 23 )
{
rv = 16;
}
}
else
{
pton_needs_space = 0;
if ( hints->ai_flags & 4 )
goto LABEL_40;
}
if ( has_serv )
{
if ( isdigit((unsigned __int8)*serv) )
{
task->serv_num = atoi(serv);
}
else
{
task->serv_num = 0;
if ( hints->ai_flags & 8 )
goto LABEL_40;
}
if ( ai_socktype_ )
{
if ( !pton_needs_space )
{
if ( !task->serv_num )
goto LABEL_6;
v23 = hints->ai_family;
if ( v23 == 2 )
{
LOWORD(v11) = 1;
}
else
{
if ( v23 != 23 )
goto LABEL_6;
LOWORD(v11) = 28;
}
LABEL_33:
task->dwordC = 4;
task->callback_0 = get_addr_info_cb_0;
task->callback_1 = get_addr_info_cb_1;
task->word2E = v11;
task->serv_name = serv;
task->callback_user = fptr;
task->p_rv = p_rv;
task->node_name = node;
task->hints = hints;
task->socktype = ai_socktype_;
task->node_net = node_net;
if ( has_node && hints && hints->ai_flags & 2 )
{
v22 = (char *)so_alloc(9, 256);
task->node_canon_name = v22;
if ( !v22 )
{
rv = -304;
goto LABEL_6;
}
v24 = strnlen(node, 0x100u);
strncpy(task->node_canon_name, node, v24);
}
else
{
task->node_canon_name = 0;
}
sub_13B52230((struct_a1 *)&unk_13C37E64, task);
return 0;
}
if ( task->serv_num )
goto LABEL_6;
}
rv = -306;
goto LABEL_6;
}
if ( !(hints->ai_flags & 8) )
{
if ( !pton_needs_space )
{
v21 = hints->ai_family;
if ( v21 == 2 )
{
v11 = 1;
}
else if ( v21 == 23 )
{
v11 = 28;
}
}
task->serv_num = 0;
if ( !v11 )
goto LABEL_6;
goto LABEL_33;
}
LABEL_40:
rv = -305;
goto LABEL_6;
}
LABEL_39:
rv = -307;
goto LABEL_6;
}
rv = -303;
LABEL_6:
if ( p_rv )
*p_rv = rv;
return rv;
}
signed int __fastcall resolve_addr_info(char *node, char *serv, so_hints *hints, SOAddrInfo **pinfo)
{
SOAddrInfo *info; // r7@1
unsigned int node_net_len; // r10@1
int v10; // r4@5
int v11; // r3@7
int v12; // r2@10
SOAddrInfo *v13; // r4@10
int v14; // r6@10
int ai_family_1; // r5@12
SOAddrInfo *info_; // r0@17
int ai_family; // r2@19
in_addr4 *v18; // r0@25
in_addr4 *ip4addr; // r4@25
void *node_net_out; // r0@26
in_addr6 *v21; // r0@38
in_addr6 *addr_any; // r4@38
int v23; // r2@40
in_addr6 *v24; // r0@14
in_addr6 *ip6addr; // r4@43
signed int result; // r0@4
char node_net_blob[140]; // [sp+Ch] [bp-F0h]@5
struct_a4 task; // [sp+98h] [bp-64h]@5
int task_rv; // [sp+D4h] [bp-28h]@5
info = 0;
node_net_len = 0;
if ( !hints )
sub_13B5ACC0("IPDns.c", 3197, "assert hints");
if ( !pinfo )
return -308;
*pinfo = 0;
start_addr_info_task(node, serv, hints, &task, node_net_blob, sub_13B51B50, &task_rv);
v10 = sub_13B5AD00();
while ( task_rv == -1 )
{
sub_13B5AE40((int *)&unk_13C3B1CC);
if ( task_rv != -1 )
break;
sub_13B5AE40((int *)&unk_13C3B1CC);
}
sub_13B5AC88(v10);
if ( task_rv <= 0 )
{
if ( task.node_canon_name )
so_free(9, task.node_canon_name, 256);
if ( task_rv != -203 && task_rv )
result = -302;
else
result = -305;
return result;
}
v11 = hints->ai_family;
if ( v11 == 2 )
{
node_net_len = 4;
v23 = task_rv;
task_rv = 0;
v13 = 0;
v14 = v23 - 4;
if ( v23 - 4 >= 0 )
goto LABEL_17;
goto LABEL_41;
}
if ( v11 == 23 )
node_net_len = 16;
v12 = task_rv;
task_rv = 0;
v13 = 0;
v14 = v12 - node_net_len;
if ( ((v12 - node_net_len) & 0x80000000) != 0 )
goto LABEL_41;
while ( 1 )
{
LABEL_17:
info_ = (SOAddrInfo *)so_alloc(10, 32);
info = info_;
if ( !info_ )
{
task_rv = -304;
so_free_addr_info(v13);
goto LABEL_46;
}
info_->flags = 0;
ai_family = hints->ai_family;
info_->family = ai_family;
info_->sockType = task.socktype;
info_->protocol = 0;
if ( ai_family == 2 )
{
info_->addrLen = 8;
}
else if ( ai_family == 23 )
{
info_->addrLen = 28;
}
if ( v14 )
{
ai_family_1 = hints->ai_family;
info_->canonName = 0;
info_->next = v13;
if ( ai_family_1 == 2 )
{
LABEL_24:
if ( hints->ai_flags & 0x10 )
{
v21 = (in_addr6 *)so_alloc(8, 28);
addr_any = v21;
info->addr = v21;
if ( !v21 )
break;
memset(v21, 0, 0x1Cu);
addr_any->len = 28;
addr_any->family = 23;
addr_any->port = task.serv_num;
node_net_out = &addr_any->addr[12];
addr_any->addr[11] = -1;
addr_any->addr[10] = -1;
}
else
{
v18 = (in_addr4 *)so_alloc(8, 8);
ip4addr = v18;
info->addr = v18;
if ( !v18 )
break;
memset(v18, 0, 8u);
ip4addr->len = 8;
ip4addr->family = ai_family_1;
ip4addr->port = task.serv_num;
node_net_out = ip4addr->addr;
}
goto LABEL_27;
}
}
else
{
info_->canonName = task.node_canon_name;
task.node_canon_name = 0;
ai_family_1 = hints->ai_family;
info_->next = v13;
if ( ai_family_1 == 2 )
goto LABEL_24;
}
if ( ai_family_1 != 23 )
goto LABEL_15;
v24 = (in_addr6 *)so_alloc(8, 28);
ip6addr = v24;
info->addr = v24;
if ( !v24 )
break;
memset(v24, 0, 0x1Cu);
ip6addr->len = 28;
ip6addr->family = 23;
node_net_out = ip6addr->addr;
ip6addr->port = task.serv_num;
LABEL_27:
memcpy_1(node_net_out, &node_net_blob[v14], node_net_len);
LABEL_15:
if ( !info->addr )
break;
v13 = info;
v14 -= node_net_len;
if ( v14 < 0 )
goto LABEL_41;
}
task_rv = -304;
so_free_addr_info(info);
info = 0;
LABEL_46:
if ( task.node_canon_name )
so_free(9, task.node_canon_name, 256);
LABEL_41:
*pinfo = info;
return task_rv;
}
int __fastcall so_get_addr_info(char *node_name, char *serv_name, void *hints, SOAddrInfo **addr_info_out)
{
so_hints *pHint; // r8@2
int v8; // r3@2
int result; // r0@5
signed int v10; // r0@8
int v11; // r4@8
int v12; // r3@13
SOAddrInfo *i; // r2@18
SOAddrInfo *v14; // [sp+0h] [bp-3Ch]@16
so_hints hint; // [sp+4h] [bp-38h]@2
if ( hints )
{
pHint = &hint;
memcpy__(&hint, hints, 0x20u);
v8 = hint.ai_family;
if ( hint.ai_family != 2 )
goto LABEL_3;
LABEL_23:
hint.ai_flags &= ~0x30u;
return resolve_addr_info(node_name, serv_name, pHint, addr_info_out);
}
pHint = &hint;
memset(&hint, 0, 0x20u);
v8 = hint.ai_family;
if ( hint.ai_family == 2 )
goto LABEL_23;
LABEL_3:
if ( v8 > 2 )
{
if ( v8 != 0x17 )
return -303;
v10 = resolve_addr_info(node_name, serv_name, pHint, addr_info_out);
v11 = v10;
if ( !(hint.ai_flags & 0x10) || !v10 && !(((unsigned int)hint.ai_flags >> 5) & 1) )
return v11;
v12 = 2;
LABEL_14:
hint.ai_family = v12;
if ( !v11 )
hint.ai_flags &= ~2u;
result = resolve_addr_info(node_name, serv_name, pHint, &v14);
if ( result >= 0 )
{
if ( v11 < 0 )
{
*addr_info_out = v14;
}
else
{
for ( i = *addr_info_out; i->next; i = i->next )
;
result = 0;
i->next = v14;
}
return result;
}
return v11;
}
if ( v8 )
return -303;
hint.ai_family = 2;
result = resolve_addr_info(node_name, serv_name, pHint, addr_info_out);
v11 = result;
if ( result >= 0 || result == -305 )
{
v12 = 23;
goto LABEL_14;
}
return result;
}
// -----------------------------------------------------------------
// /dev/net/ip/top dispatcher
// -----------------------------------------------------------------
...
case 0x18:
v17 = *(iov **)(v76 + 24);
addr_info_io = (SOAddrInfo *)v17[3].ptr;
v6 = so_get_addr_info((char *)v17->ptr, (char *)v17[1].ptr, (void *)v17[2].ptr, &addr_info);
if ( v6 )
goto LABEL_14;
v19 = addr_info;
v20 = addr_info;
v21 = *(_DWORD *)(*(_DWORD *)(v3 + 24) + 28) >> 5;
v22 = addr_info_io + 0x23;
if ( !addr_info || v21 <= 0 )
goto LABEL_36;
break;
...
while ( 1 )
{
memcpy__(addr_info_io, v20, 0x20u);
memcpy__(v22, v20->addr, v20->addrLen);
v20 = v20->next;
v22 = (SOAddrInfo *)((char *)v22 + 0x1C);
if ( !v20 )
break;
++addr_info_io;
--v21;
if ( !v20 || v21 <= 0 )
goto LABEL_35;
}
addr_info_io->next = 0;
LABEL_35:
v19 = addr_info;
LABEL_36:
so_free_addr_info(v19);
v0 = 0;
}
LABEL_4:
sub_13B64FE4(v3, v0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment