这个地址找到了,
CSharedMemStream has memory already locked for put. Don’t write with memory locked.
这个调试信息告诉我们。100%共享内存
现在查看共享内存名字吧!
直接给 F5代码吧!
__int64 __fastcall CSharedMemStream_1800B05E0(__int64 a1, const char *a2, unsigned int a3, int a4, unsigned int a5, char a6)
{
const char *v6; // rbp
__int64 v7; // rbx
unsigned int v8; // edi
unsigned int v9; // eax
char v10; // bp
_QWORD *v11; // rax
__int64 v12; // rax
__int64 v13; // r8
__int64 v14; // r9
const char *v15; // rcx
__int64 v16; // rax
unsigned __int8 (__fastcall ***v17)(_QWORD); // rax
unsigned int *v18; // rax
char v19; // cl
__int64 v20; // r9
char DstBuf; // [rsp+40h] [rbp-118h]
char v23; // [rsp+170h] [rbp+18h]
v6 = a2;
v7 = a1;
(_QWORD )a1 = &CSharedMemStream::`vftable’;
v8 = 512;
if ( a3 > 0x200 )
v8 = a3;
(_WORD )(a1 + 328) = 0;
(_QWORD )(a1 + 272) = 0i64;
(_QWORD )(a1 + 280) = 0i64;
(_QWORD )(a1 + 288) = 0i64;
(_QWORD )(a1 + 320) = 0i64;
(_DWORD )(a1 + 296) = v8;
(_DWORD )(a1 + 304) = a4;
(_BYTE )(a1 + 330) = 0;
(_BYTE )(a1 + 332) = 0;
if ( a5 )
{
v9 = v8;
if ( a5 < v8 )
v9 = a5;
}
else
{
v9 = 1;
if ( v8 / 0x19 > 1 )
v9 = v8 / 0x19;
}
(_DWORD )(a1 + 300) = v9;
(_QWORD )(a1 + 0x150) = malloc_1800BAAF0(v9);
(_QWORD )(v7 + 344) = 0i64;
strncpy((char *)(v7 + 8), v6, 0x100ui64);
sprintf_s_1(&DstBuf, 0x100ui64, “%s_mutex”, v7 + 8);
LOBYTE(a5) = 0;
v23 = 0;
v10 = a6;
v11 = mutex_180098A70(&DstBuf, 1u, &a5, a6);
(_QWORD )(v7 + 264) = v11;
if ( v11 )
{
if ( !(_BYTE)a5 )
((void (__fastcall *)(_QWORD *, signed __int64))*v11)(v11, 0xFFFFFFFFi64);
sprintf_s_1(&DstBuf, 0x100ui64, “%s_written”, v7 + 8);
v12 = event_180098910(&DstBuf, 0, 0, 0i64, v10);
(_QWORD )(v7 + 280) = v12;
if ( !v12 )
{
v15 = “Failed creating write event %s\n”;
LABEL_20:
sub_1800996F0((__int64)v15, (__int64)&DstBuf, v13, v14);
((void (__cdecl )(_QWORD))((_QWORD *)(v7 + 264) + 32i64))((_QWORD )(v7 + 264));
return v7;
}
sprintf_s_1(&DstBuf, 0x100ui64, “%s_avail”, v7 + 8);
v16 = event_180098910(&DstBuf, 0, 0, 0i64, v10);
(_QWORD )(v7 + 0x120) = v16;
if ( !v16 )
{
v15 = “Failed creating read event %s\n”;
goto LABEL_20;
}
sprintf_s_1(&DstBuf, 0x100ui64, “%s_mem”, v7 + 8);
v17 = (unsigned __int8 (__fastcall *)(_QWORD))create_map_180098BC0(&DstBuf, v8 + 16, 2, (bool *)&v23);
(_QWORD )(v7 + 272) = v17;
if ( !v17 )
{
v15 = “Failed creating file mapping %s\n”;
goto LABEL_20;
}
if ( !(**v17)(v17) )
{
v15 = “Failed creating view of file for %s\n”;
goto LABEL_20;
}
v18 = (unsigned int )((__int64 (__cdecl )(_QWORD))((_QWORD *)(v7 + 272) + 8i64))((_QWORD *)(v7 + 272));
(_QWORD )(v7 + 0x140) = v18;
v19 = v23;
(_BYTE )(v7 + 0x14A) = v23;
if ( v19 )
{
memset(v18, 0, v8 + 16i64);
(_DWORD )((_QWORD )(v7 + 0x140) + 8i64) = v8;
}
else
{
v20 = v18[2];
if ( (_DWORD)v20 == v8 )
{
(_DWORD )(v7 + 0x128) = v8;
}
else
{
sub_1800996F0(
(__int64)”Size on connection to existing CSharedMemStream doesn’t match actual: %s, %u, %u”,
(__int64)&DstBuf,
v8,
v20);
(_DWORD )(v7 + 0x128) = 0;
}
}
((void (__cdecl )(_QWORD))((_QWORD *)(v7 + 264) + 32i64))((_QWORD )(v7 + 264));
(_QWORD )(v7 + 0x138) = (_QWORD )(v7 + 320) + 16i64;
(_BYTE )(v7 + 0x148) = 1;
}
return v7;
}
可以看出他是用的event 做通信控制 共享内存做信息载体
具体怎么逆向这个共享内存的格式我就不细说了。主要是分析共享内存的结构体,
#pragma pack(push) //保存对齐状态
#pragma pack(1)//设定为4字节对齐
typedef struct strshareMem
{
DWORD Mem_data_Head_off;//有用数据头部偏移
DWORD Mem_data_tail_off;//有用数据尾部偏移
DWORD p3; //保留数据
DWORD Mem_data_Unprocessed_count;//未处理数据量
char data [0x1000000];
}mystrshareMem,*pmystrshareMem;
#pragma pack(pop)//恢复对齐状态
这个是他图片显示的共享内存结构体,采用的是环形存放格式
共享内存写入逻辑我已经逆向处源码了
int write_mem_data(char * data ,int datalen)
{
int copyedlen = datalen;
BYTE unknow =NULL;//标识mx是否成功的 1标识失败 0标识成功
while (1)
{
if(unknow)
{
goto LABEL_10;
}
//DWORD * MemHasUsed=(DWORD *)((ULONG_PTR)g_p_ShareMem +0xc);
if (g_mem_maxSize - g_p_ShareMem->Mem_data_Unprocessed_count < datalen)
{
break;
}
LABEL_8:
if(!unknow && WaitForSingleObject(g_h_Mutex,-1)!=0)
{
MessageBoxA(NULL,__FUNCTION__,"148",MB_OK);
return 0;
}
LABEL_10:
if (g_p_ShareMem->Mem_data_tail_off > g_mem_maxSize)
{
ReleaseMutex(g_h_Mutex);
return 0;
}
if (g_mem_maxSize - g_p_ShareMem->Mem_data_Unprocessed_count >= datalen)
{
char * data_mem = &(g_p_ShareMem->data[g_p_ShareMem->Mem_data_tail_off]);
if (g_p_ShareMem->Mem_data_tail_off+datalen <= g_mem_maxSize)
{
memcpy(data_mem,data,datalen);
g_p_ShareMem->Mem_data_tail_off += datalen;
}else
{
int copyed_size = g_mem_maxSize - g_p_ShareMem->Mem_data_tail_off;
memcpy(data_mem,data,copyed_size);
memcpy(g_p_ShareMem->data,data+copyed_size,datalen - copyed_size);
g_p_ShareMem->Mem_data_tail_off = datalen-copyed_size;
copyedlen = datalen;
}
if (!unknow)
{
g_p_ShareMem->Mem_data_Unprocessed_count += copyedlen;
SetEvent(g_h_Event_Written);
ReleaseMutex(g_h_Mutex);
}
return copyedlen;
}
if (unknow)
{
//空间不足
return 0;
}
ReleaseMutex(g_h_Mutex);
}
while(WaitForSingleObject(g_h_Event_Avail,g_maxTime)!=0)
{
if (g_mem_maxSize - *(DWORD *)((ULONG_PTR)g_p_ShareMem +0xc) >= datalen )
{
goto LABEL_8;
}
}
//等待超时
return 0;
}