关于C3dServer

最近在用C3dServer将一些文本格式的marker点数据转换为.c3d格式,可是marker点的名称一直没法很好地设置。本来这个名称是存储在Group/POINT/LABELS里面的,可是默认的名称长度只有6,所以只能用AddParameter重建这个参数。可是我一直没重建成功,代码如下:

int iLabelNameId = p->GetParameterIndex(_bstr_t(L"Point"), _bstr_t(L"Labels"));nRes = p->DeleteParameter(iLabelNameId);
int nRes = p->AddParameter(BSTR(L"LABELS"), BSTR(L"Marker Names"), BSTR(L"POINT"), 0, -1, 2, varDims, varMNames);

VARIANT varDims;
{
    int *pDim = NULL;
    VariantInit( &varDims );
    SAFEARRAY *psaDim = SafeArrayCreateVector(VT_INT, 0, 2 );
    pDim[0] = 64; pDim[1] = 32;
    SafeArrayUnaccessData( psaDim );

    varDims.vt = VT_ARRAY | VT_INT;
    varDims.parray = psaDim;    
}

今天用IDA调试了一下,终于发现了问题。

v32 = psa;
if ( SafeArrayGetLBound(psa, 1u, &plLbound) < 0 )
  SafeArrayGetUBound(v32, 1u, &plUbound);
SafeArrayAccessData(v32, &ppvData);
if ( v32->rgsabound[0].cElements >= (unsigned int)v29 )
{
  for ( j = 0; j < (signed int)v29; ++j )
  {
    v34 = *((_WORD *)ppvData + j);
    if ( v34 >= 0 )
      *(_BYTE *)(*(_DWORD *)(v27 + 52) + j) = v34;
  }
}
SafeArrayUnaccessData(v32);

这是IDA反编译出来的C代码(sub_10004CCE)。可以看到它用的是_WORD,所以把varDims从int改为short就可以了。

关于C3dServer的破解:搜索Sleep函数就可以找到相应地址,nop掉即可。还可以用RegOpenKey找到sub_1000248C函数,将line 142 *(_DWORD *)(v7 + 304) = 1;中的1改为2。64位类似。

关于IDA:IDA没有自带64位的调试器,需要安装WinDbg,挺麻烦的。而且IDA调试不支持查看内存,无法设置内存断点,只能配合VS使用。另外发现一个反汇编的网站挺好用的:https://www.onlinedisassembler.com/odaweb/,支持64位。

你可能感兴趣的:(关于C3dServer)