image-20220510205237513

发票提取工具比较感兴趣,今天就分析看看

1.界面

image-20220510205426661

spy++看看,delphi程序,jdls 是不是交大龙山

image-20220510205718575

2.安装目录

image-20220510211303634

3.发票提取

分析下FPTQ目录

image-20220510212151762

dll文件 导出函数
AISINO30DBCOLLECTOR_V2.DLL aisino30OpenSql
decryptInvMw
getMainVer
setDataEngineInitWaitTime
startDataEngine
terminateDataEngine
HXSERVERFPTQ.DLL ExportFpByRqqj
GetKpjNsrxx
AISINO30DBENGINER_V2.DLL getOpe
getOpe2
getOpe3
getOpe4
getOpe5
openSql
AISINO30REMOTEINJECT.DLL getOpe
getOpe2
getOpe3
getOpe4
getOpe5
openSql

3.1HXSERVERFPTQ.dll

delphi反汇编效果不太好,看参数是7个

char __userpurge ExportFpByRqqj@<al>(int a1@<ebx>, int a2, int a3, int a4, int a5, int a6, char **a7)
{
  int v7; // eax@1
  int v8; // eax@1
  int v9; // edx@2
  unsigned int v11; // [sp-1Ch] [bp-3Ch]@1
  _UNKNOWN *v12; // [sp-18h] [bp-38h]@1
  _DWORD *v13; // [sp-14h] [bp-34h]@1
  unsigned __int32 v14; // [sp-10h] [bp-30h]@1
  _UNKNOWN *v15; // [sp-Ch] [bp-2Ch]@1
  _DWORD *v16; // [sp-8h] [bp-28h]@1
  int v17; // [sp-4h] [bp-24h]@1
  int v18; // [sp+0h] [bp-20h]@1
  int v19; // [sp+4h] [bp-1Ch]@1
  int v20; // [sp+8h] [bp-18h]@1
  int v21; // [sp+Ch] [bp-14h]@1
  int v22; // [sp+10h] [bp-10h]@1
  int v23; // [sp+14h] [bp-Ch]@1
  System::TObject *v24; // [sp+18h] [bp-8h]@1
  char v25; // [sp+1Fh] [bp-1h]@1
  _UNKNOWN *savedregs; // [sp+20h] [bp+0h]@1

  v23 = 0;
  v22 = 0;
  v21 = 0;
  v20 = 0;
  v19 = 0;
  v18 = 0;
  v17 = a1;
  v16 = &savedregs;
  v15 = &loc_451DE2;
  v14 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v14);
  v24 = (System::TObject *)Rio::_16398(dword_451C30, 1);
  v13 = &savedregs;
  v12 = &loc_451DC0;
  v11 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v11);
  unknown_libname_62(&v23, a2);
  unknown_libname_493(v24, v23);
  *((_BYTE *)v24 + 4) = 1;
  unknown_libname_62(&v22, a3);
  unknown_libname_491(v24, v22);
  unknown_libname_62(&v21, a4);
  unknown_libname_492(v24, v21);
  v7 = sub_43F9EC(a5);
  unknown_libname_62(&v20, v7);
  unknown_libname_490(v24, v20);
  v8 = sub_43F9EC(a6);
  unknown_libname_62(&v19, v8);
  sub_454774(v24, v19);
  unknown_libname_62(&v18, *a7);
  Wsdlnode::TWSDLView::SetOperation(v24, v18);
  v25 = sub_4547D8(v24);
  if ( !v25 )
  {
    v9 = *((_DWORD *)v24 + 11);
    Sysutils::StrPCopy(*a7);
  }
  __writefsdword(0, v11);
  v13 = &loc_451DC7;
  System::TObject::Free(v24);
  __writefsdword(0, (unsigned int)v24);
  savedregs = &loc_451DE9;
  System::__linkproc__ LStrArrayClr(&v18, 6);
  return v25;
}

调用的dll看不出名字来,先一放,看看其他dll

3.2AISINO30DBCOLLECTOR_V2.DLL

这个有意思,看看他的几个函数

函数 大体猜下意思
getMainVer 获取主版本号
decryptInvMw 解密发票密文
terminateDataEngine 结束数据引擎
startDataEngine 启动数据引擎
setDataEngineInitWaitTime 设置引擎初始化时间
aisino30OpenSql 航信3.0打开sql

3.2.1aisino30OpenSql

又是delphi写的,有意思8个参数,想想上面是不是7个,有没有可能是上面调用的它

int __cdecl aisino30OpenSql(int a1, char *a2, int a3, int a4, int a5, int a6, char *a7, int a8)
{
  int v8; // eax@1
  int v9; // eax@1
  int v10; // eax@1
  int v11; // eax@2
  int v12; // eax@5
  int v13; // eax@7
  int v14; // eax@9
  char v15; // zf@10
  int v16; // eax@16
  int v17; // eax@18
  int v18; // eax@20
  int v19; // eax@22
  int v20; // eax@25
  int v21; // eax@26
  int v22; // eax@27
  int v23; // eax@29
  HMODULE v24; // edi@30
  const char *v25; // eax@30
  const char *v26; // eax@30
  const char *v27; // eax@30
  const char *v28; // eax@30
  const char *v29; // eax@32
  int v30; // eax@33
  int v31; // eax@35
  int v32; // eax@37
  int v33; // eax@39
  int v34; // eax@41
  HANDLE v35; // ebx@42
  int v36; // eax@43
  int v37; // eax@45
  int v38; // ebx@46
  int v39; // eax@52
  const char *v40; // eax@54
  int result; // eax@57
  unsigned __int64 v42; // [sp+0h] [bp-2E74h]@1
  unsigned int v43; // [sp+8h] [bp-2E6Ch]@1
  unsigned int v44; // [sp+Ch] [bp-2E68h]@1
  int *v45; // [sp+10h] [bp-2E64h]@1
  int *v46; // [sp+14h] [bp-2E60h]@1
  unsigned __int32 v47; // [sp+18h] [bp-2E5Ch]@1
  _UNKNOWN *v48; // [sp+1Ch] [bp-2E58h]@1
  int *v49; // [sp+20h] [bp-2E54h]@1
  int v50; // [sp+30h] [bp-2E44h]@45
  int v51; // [sp+34h] [bp-2E40h]@43
  int v52; // [sp+38h] [bp-2E3Ch]@41
  int v53; // [sp+3Ch] [bp-2E38h]@39
  int v54; // [sp+40h] [bp-2E34h]@37
  int v55; // [sp+44h] [bp-2E30h]@35
  int v56; // [sp+48h] [bp-2E2Ch]@33
  DWORD v57; // [sp+4Ch] [bp-2E28h]@33
  char v58; // [sp+50h] [bp-2E24h]@33
  int v59; // [sp+54h] [bp-2E20h]@33
  char v60; // [sp+58h] [bp-2E1Ch]@33
  int *v61; // [sp+5Ch] [bp-2E18h]@29
  char v62; // [sp+60h] [bp-2E14h]@29
  int v63; // [sp+64h] [bp-2E10h]@26
  int v64; // [sp+68h] [bp-2E0Ch]@24
  int v65; // [sp+6Ch] [bp-2E08h]@21
  int v66; // [sp+70h] [bp-2E04h]@8
  int v67; // [sp+74h] [bp-2E00h]@4
  int v68; // [sp+78h] [bp-2DFCh]@4
  FARPROC Buffer; // [sp+7Ch] [bp-2DF8h]@30
  FARPROC v70; // [sp+80h] [bp-2DF4h]@30
  FARPROC v71; // [sp+84h] [bp-2DF0h]@30
  char v72; // [sp+88h] [bp-2DECh]@30
  char v73; // [sp+18Dh] [bp-2CE7h]@30
  char v74; // [sp+20Eh] [bp-2C66h]@30
  char v75; // [sp+313h] [bp-2B61h]@30
  char v76; // [sp+393h] [bp-2AE1h]@30
  char v77; // [sp+1794h] [bp-16E0h]@30
  char v78; // [sp+1899h] [bp-15DBh]@32
  DWORD v79; // [sp+191Ch] [bp-1558h]@46
  char v80; // [sp+1920h] [bp-1554h]@32
  char v81; // [sp+2D21h] [bp-153h]@32
  int v82; // [sp+2E28h] [bp-4Ch]@1
  int v83; // [sp+2E2Ch] [bp-48h]@10
  int v84; // [sp+2E30h] [bp-44h]@26
  int v85; // [sp+2E34h] [bp-40h]@8
  int v86; // [sp+2E38h] [bp-3Ch]@46
  int v87; // [sp+2E3Ch] [bp-38h]@1
  int v88; // [sp+2E40h] [bp-34h]@26
  int v89; // [sp+2E44h] [bp-30h]@26
  LPTHREAD_START_ROUTINE lpStartAddress; // [sp+2E48h] [bp-2Ch]@1
  LPVOID lpBaseAddress; // [sp+2E4Ch] [bp-28h]@1
  HANDLE hProcess; // [sp+2E50h] [bp-24h]@1
  DWORD NumberOfBytesRead; // [sp+2E54h] [bp-20h]@44
  DWORD ExitCode; // [sp+2E58h] [bp-1Ch]@44
  DWORD ThreadId; // [sp+2E5Ch] [bp-18h]@42
  DWORD NumberOfBytesWritten; // [sp+2E60h] [bp-14h]@36
  SIZE_T nSize; // [sp+2E64h] [bp-10h]@38
  SIZE_T dwSize; // [sp+2E68h] [bp-Ch]@34
  DWORD dwProcessId; // [sp+2E6Ch] [bp-8h]@28
  DWORD v100; // [sp+2E70h] [bp-4h]@1
  int savedregs; // [sp+2E74h] [bp+0h]@1

  v49 = &savedregs;
  v48 = &loc_47073E;
  v47 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v47);
  v100 = 0;
  hProcess = 0;
  System::__linkproc__ LStrClr(&v87);
  lpBaseAddress = 0;
  lpStartAddress = 0;
  v8 = unknown_libname_118(a1, &v82);
  v46 = &savedregs;
  v45 = (int *)&loc_4706F9;
  v44 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v44);
  v43 = (unsigned int)&savedregs;
  v42 = __PAIR__(&loc_470598, __readfsdword(0));
  __writefsdword(0, (unsigned int)&v42);
  v9 = sub_46DCA4(v8);
  v10 = sub_46EDC8(v9);
  if ( !(unsigned __int8)sub_46F230(v10) )
  {
    v11 = Websnapobjs::TPageObj::TPageObj(&str_collect_data_no[1]);
    System::__linkproc__ RaiseExcept(v11);
  }
  if ( !a1 || (unknown_libname_118(a1, &v67), Sysutils::Trim(v67, &v68), !v68) )
  {
    v12 = Websnapobjs::TPageObj::TPageObj(&str_database_path_i[1]);
    System::__linkproc__ RaiseExcept(v12);
  }
  if ( !a3 )
  {
    v13 = Websnapobjs::TPageObj::TPageObj(&str_out_data_direct[1]);
    System::__linkproc__ RaiseExcept(v13);
  }
  unknown_libname_118(a3, &v66);
  Sysutils::Trim(v66, &v85);
  if ( !v85 )
  {
    v14 = Websnapobjs::TPageObj::TPageObj(&str_out_data_direct[1]);
    System::__linkproc__ RaiseExcept(v14);
  }
  unknown_libname_73(v85);
  System::__linkproc__ LStrCopy(&v83);
  System::__linkproc__ LStrCmp(v83, &str___20[1]);
  if ( !v15 )
  {
    System::__linkproc__ LStrCmp(v83, &str___21[1]);
    if ( !v15 )
      System::__linkproc__ LStrCat(&v85, &str___20[1]);
  }
  if ( !(unsigned __int8)Sysutils::DirectoryExists(v85) )
    Sysutils::CreateDir(v85);
  if ( !(unsigned __int8)Sysutils::DirectoryExists(v85) )
  {
    v16 = Websnapobjs::TPageObj::TPageObj(&str_out_data_direct_0[1]);
    System::__linkproc__ RaiseExcept(v16);
  }
  if ( (unsigned int)a8 < 0x104 )
  {
    v17 = Websnapobjs::TPageObj::TPageObj(&str_out_data_file_b_0[1]);
    System::__linkproc__ RaiseExcept(v17);
  }
  if ( !a2 )
  {
    v18 = Websnapobjs::TPageObj::TPageObj(&str_sql_is_null[1]);
    System::__linkproc__ RaiseExcept(v18);
  }
  unknown_libname_118(a2, &v65);
  if ( unknown_libname_73(v65) > 5120 )
  {
    v19 = Websnapobjs::TPageObj::TPageObj(&str_sql_is_too_long[1]);
    System::__linkproc__ RaiseExcept(v19);
  }
  if ( a4 )
  {
    unknown_libname_118(a4, &v64);
    if ( unknown_libname_73(v64) > 128 )
    {
      v20 = Websnapobjs::TPageObj::TPageObj(&str_data_tag_too_lo[1]);
      System::__linkproc__ RaiseExcept(v20);
    }
  }
  sub_46F938(v82, &v89, &v88);
  Texttestrunner::RunRegisteredTests(&v63);
  System::__linkproc__ LStrCat3(&v84, v63, &str_Aisino30DbEngin_3[1]);
  v21 = Sysutils::FileExists(v84);
  if ( !(_BYTE)v21 )
  {
    v22 = Websnapobjs::TPageObj::TPageObj(&str_database_operat_3[1]);
    v21 = System::__linkproc__ RaiseExcept(v22);
  }
  dwProcessId = sub_46F5C8(v21);
  if ( !dwProcessId )
  {
    v61 = &str_start_fail[1]._top;
    v62 = 11;
    v23 = sub_4319D8(0, &v61, &str_start_database__0[1]);
    System::__linkproc__ RaiseExcept(v23);
  }
  v24 = GetModuleHandleA_0("Kernel32.dll");
  Buffer = GetProcAddress_0(v24, "LoadLibraryA");
  v70 = GetProcAddress_0(v24, "FreeLibrary");
  v71 = GetProcAddress_0(v24, "GetProcAddress");
  v25 = (const char *)System::__linkproc__ LStrToPChar(v84);
  Sysutils::StrCopy(&v72, v25);
  Sysutils::StrCopy(&v73, "openSql");
  v26 = (const char *)System::__linkproc__ LStrToPChar(v89);
  Sysutils::StrCopy(&v74, v26);
  v27 = (const char *)System::__linkproc__ LStrToPChar(v88);
  Sysutils::StrCopy(&v75, v27);
  Sysutils::StrCopy(&v76, a2);
  v28 = (const char *)System::__linkproc__ LStrToPChar(v85);
  Sysutils::StrCopy(&v77, v28);
  System::__linkproc__ LStrClr(&v83);
  if ( a4 )
    unknown_libname_118(a4, &v83);
  v29 = (const char *)System::__linkproc__ LStrToPChar(v83);
  Sysutils::StrCopy(&v78, v29);
  System::__linkproc__ FillChar(&v80, 5121, 0);
  System::__linkproc__ FillChar(&v81, 261, 0);
  hProcess = OpenProcess(0x1F0FFFu, 0, dwProcessId);
  if ( !hProcess )
  {
    v57 = GetLastError();
    v58 = 0;
    sub_46DEC8(&v56);
    v59 = v56;
    v60 = 11;
    v30 = sub_4319D8(1, &v57, &str_open_database_e[1]);
    System::__linkproc__ RaiseExcept(v30);
  }
  dwSize = 11692;
  lpBaseAddress = VirtualAllocEx(hProcess, 0, 0x2DACu, 0x1000u, 4u);
  if ( !lpBaseAddress )
  {
    v57 = GetLastError();
    v58 = 0;
    sub_46DEC8(&v55);
    v59 = v55;
    v60 = 11;
    v31 = sub_4319D8(1, &v57, &str_allocate_memory[1]);
    System::__linkproc__ RaiseExcept(v31);
  }
  if ( (unsigned int)WriteProcessMemory(hProcess, lpBaseAddress, &Buffer, dwSize, &NumberOfBytesWritten) < 1 )
  {
    v57 = GetLastError();
    v58 = 0;
    sub_46DEC8(&v54);
    v59 = v54;
    v60 = 11;
    v32 = sub_4319D8(1, &v57, &str_write_memory_to[1]);
    System::__linkproc__ RaiseExcept(v32);
  }
  nSize = (char *)nullsub_3 - (char *)(int (*)())sub_46F4F0;
  lpStartAddress = (LPTHREAD_START_ROUTINE)VirtualAllocEx(
                                             hProcess,
                                             0,
                                             (char *)nullsub_3 - (char *)(int (*)())sub_46F4F0,
                                             0x1000u,
                                             0x40u);
  if ( !lpStartAddress )
  {
    v57 = GetLastError();
    v58 = 0;
    sub_46DEC8(&v53);
    v59 = v53;
    v60 = 11;
    v33 = sub_4319D8(1, &v57, &str_allocate_memory[1]);
    System::__linkproc__ RaiseExcept(v33);
  }
  if ( (unsigned int)WriteProcessMemory(hProcess, lpStartAddress, sub_46F4F0, nSize, &NumberOfBytesWritten) < 1 )
  {
    v57 = GetLastError();
    v58 = 0;
    sub_46DEC8(&v52);
    v59 = v52;
    v60 = 11;
    v34 = sub_4319D8(1, &v57, &str_write_memory_to[1]);
    System::__linkproc__ RaiseExcept(v34);
  }
  v35 = CreateRemoteThread(hProcess, 0, 0, lpStartAddress, lpBaseAddress, 0, &ThreadId);
  if ( !v35 )
  {
    v57 = GetLastError();
    v58 = 0;
    sub_46DEC8(&v51);
    v59 = v51;
    v60 = 11;
    v36 = sub_4319D8(1, &v57, &str_database_engine_1[1]);
    System::__linkproc__ RaiseExcept(v36);
  }
  WaitForSingleObject(v35, 0xFFFFFFFF);
  ExitCode = Sysutils::StrToInt(&str_9999_0[1]);
  GetExitCodeThread(v35, &ExitCode);
  v100 = ExitCode;
  if ( (unsigned int)ReadProcessMemory(hProcess, lpBaseAddress, &Buffer, 0x2DACu, &NumberOfBytesRead) < 1 )
  {
    v57 = GetLastError();
    v58 = 0;
    sub_46DEC8(&v50);
    v59 = v50;
    v60 = 11;
    v37 = sub_4319D8(1, &v57, &str_read_memory_fro[1]);
    System::__linkproc__ RaiseExcept(v37);
  }
  v100 = v79;
  unknown_libname_72(&v87, &v80, 5121);
  unknown_libname_72(&v86, &v81, 261);
  __writefsdword(0, v42);
  __writefsdword(0, v44);
  v46 = (int *)&loc_470703;
  v45 = &savedregs;
  v44 = (unsigned int)&loc_47068E;
  v43 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v43);
  v38 = unknown_libname_73(v87);
  v42 = v38;
  if ( (unsigned __int64)v38 >> 32 )
  {
    if ( SHIDWORD(v42) < 0 )
      goto LABEL_51;
  }
  else if ( a6 > (unsigned int)v42 )
  {
    goto LABEL_51;
  }
  v38 = a6 - 1;
LABEL_51:
  if ( a5 )
  {
    System::__linkproc__ FillChar(a5, a6, 0);
    v39 = System::__linkproc__ LStrToPChar(v87);
    sub_40700C(a5, v39, v38);
  }
  if ( v100 )
  {
    if ( a7 )
      System::__linkproc__ FillChar(a7, a8, 0);
  }
  else
  {
    v40 = (const char *)System::__linkproc__ LStrToPChar(v86);
    Sysutils::StrCopy(a7, v40);
  }
  result = 0;
  __writefsdword(0, v43);
  if ( hProcess )
    result = CloseHandle(hProcess);
  if ( lpBaseAddress )
    result = VirtualFreeEx(hProcess, lpBaseAddress, dwSize, 0x8000u);
  if ( lpStartAddress )
    result = VirtualFreeEx(hProcess, lpStartAddress, nSize, 0x8000u);
  return result;
}

这个有意思,上面调用了

 Sysutils::StrCopy(&v73, "openSql");

这个opensql函数再AISINO30DBENGINER_V2.DLL 、AISINO30REMOTEINJECT.DLL 都出现了,可能就是调用的里面的,再大胆猜测下,这个是执行sql,执行sql之前是不是要做初始化,启动之类的,看看startDataEngine函数干了些啥

int __usercall startDataEngine@<eax>(long double a1@<st0>, int a2, int a3)
{
  int result; // eax@1
  unsigned int v6; // [sp-Ch] [bp-38h]@1
  _UNKNOWN *v7; // [sp-8h] [bp-34h]@1
  int *v8; // [sp-4h] [bp-30h]@1
  unsigned __int64 v9; // [sp+0h] [bp-2Ch]@1
  int *v10; // [sp+8h] [bp-24h]@1
  unsigned __int32 v11; // [sp+Ch] [bp-20h]@1
  _UNKNOWN *v12; // [sp+10h] [bp-1Ch]@1
  int *v13; // [sp+14h] [bp-18h]@1
  int v14; // [sp+24h] [bp-8h]@1
  int v15; // [sp+28h] [bp-4h]@1
  int savedregs; // [sp+2Ch] [bp+0h]@1

  v14 = 0;
  v13 = &savedregs;
  v12 = &loc_470C85;
  v11 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v11);
  v10 = &savedregs;
  v9 = __PAIR__(&loc_470C68, __readfsdword(0));
  __writefsdword(0, (unsigned int)&v9);
  v8 = &savedregs;
  v7 = &loc_470BB0;
  v6 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v6);
  sub_46F5C8(a1);
  System::__linkproc__ LStrClr(&v14);
  v15 = 0;
  __writefsdword(0, v6);
  result = 0;
  __writefsdword(0, v9);
  v10 = (int *)&loc_470C6F;
  return result;
}

sub_46F5C8看看这个函数

image-20220510214829202

选中v17看看哪里调用了

image-20220510215029754

看看sub_46F558这个函数

image-20220510215153727

str_third_dataengin点击下

image-20220510215240956

他是调用了third\dataengine_v2.exe

image-20220510215337495

惊喜吧,这就是个开票软件啊,看来他是需要启动税控系统

od分析下,看看有没有有用的字符串

image-20220510220221683

image-20220510220611876

上面纯属猜测,想想那7,8个参数会是啥,首先采集需要知道这几个元素

1、数据库路径

2、sql语句,看opensql应该是提供了直接发送sql语句,如果不是,那就需要2个参数,日期起、日期至

3、提到了输出,那就还有个输出目录

参数还不够,路径再想想有没有这种这可能,路径是航信安装目录,在加个税号作为参数

换个工具,看看他内部怎么调用

image-20220510221912766

还有个dll,看样他才是入口

image-20220510222142284

没有导出函数,该休息了,有时间再继续

posted on 2022-05-10 22:31  陆战队  阅读(289)  评论(0编辑  收藏  举报