2016-02-02 5 views
1

Я декомпилировал некоторую dll с использованием Hex-Rays, а затем попытался скомпилировать ее снова как MATLAB MEX. Поскольку Hex декомпилирует double * как int, и я использую win 7 64 i casted double * using uintptr_t. К сожалению, иногда я получаю «segmentation fault».Hex-rays, MATLAB, MEX, литье uintptr_t не работает

Вот мой код

#include "mex.h" 
#include <stdint.h> 

double __stdcall dzSell(int a1, double a2, int a3, int a4, int a5) 
{ 
    int v5; // [email protected] 
    double v6; // [email protected] 
    double result; // [email protected] 
    int v8; // [email protected] 
    double v9; // [email protected] 
    double v10; // [email protected] 
    int v11; // [email protected] 
    int v12; // [email protected] 
    int v13; // [email protected] 
    double v14; // [email protected] 
    double v15; // [email protected] 
    double v16; // [email protected] 
    double v17; // [email protected] 
    double v18; // [email protected] 
    double v19; // [email protected] 
    double v20; // [email protected] 
    double v21; // [email protected] 
    double v22; // [email protected] 
    double v23; // [email protected] 
    double v24; // [email protected] 
    double v25; // [email protected] 
    double v26; // [email protected] 
    double v27; // [email protected] 
    double v28; // [email protected] 
    double v29; // [email protected] 
    int v30; // [email protected] 
    int v31; // [email protected] 
    double v32; // [email protected] 
    double v33; // [email protected] 
    double v34; // [email protected] 
    double v35; // [email protected] 
    signed int v36; // [email protected] 
    double v37; // [email protected] 
    double v38; // [email protected] 
    double v39; // [email protected] 
    double v40; // [email protected] 
    double v41; // [email protected] 
    double v42; // [email protected] 
    double v43; // [email protected] 
    signed int v44; // [email protected] 
    double v45; // [email protected] 
    int v46; // [email protected] 
    int v47; // [email protected] 
    double v48; // [email protected] 
    double v49; // [email protected] 
    double v50; // [email protected] 
    double v51; // [email protected] 
    double v52; // [email protected] 
    double v53; // [email protected] 
    double v54; // [email protected] 
    double v55; // [email protected] 
    double v56; // [email protected] 
    double v57; // [email protected] 
    double v58; // [sp+4h] [bp-8h]@3 
    int v59; // [sp+20h] [bp+14h]@1 
    int v60; // [sp+20h] [bp+14h]@5 

    v5 = a4 - a5; 
    v59 = a4 - a5; 
    if (v59 >= a3) 
    v59 = a3; 
    v6 = (double)v59; 
    v58 = v6; 
    if (v6 >= 1.0) 
    { 
    v8 = v5 - 1; 
    v9 = *(double *)(a1 + 8 * (v5 - 1)); 
    v10 = v9; 
    v60 = a1 + 8 * (v5 - 1); 
    v11 = 1; 
    if (a3 - 1 < 4) 
    { 
LABEL_28: 
     if (v11 < a3) 
     { 
     v30 = v8 - v11; 
     v31 = a1 + 8 * (v8 - v11); 
     do 
     { 
      if (v30 < 0) 
      break; 
      if (v10 < *(double *)v31) 
      v10 = *(double *)v31; 
      v32 = v10; 
      v33 = v9; 
      v34 = v32; 
      if (v33 > *(double *)v31) 
      v33 = *(double *)v31; 
      ++v11; 
      v35 = v33; 
      v10 = v34; 
      v9 = v35; 
      v31 -= 8; 
      --v30; 
     } 
     while (v11 < a3); 
     } 
    } 
    else 
    { 
     v12 = v5 - 4; 
     v13 = a1 + 8 * (v5 - 4); 
     while (v12 + 2 >= 0) 
     { 
     if (v10 < *(double *)(v13 + 16)) 
      v10 = *(double *)(v13 + 16); 
     v14 = v10; 
     v15 = v9; 
     v16 = v14; 
     if (v15 > *(double *)(v13 + 16)) 
      v15 = *(double *)(v13 + 16); 
     v17 = v15; 
     v10 = v16; 
     v9 = v17; 
     if (v12 + 1 < 0) 
      break; 
     if (v10 < *(double *)(v13 + 8)) 
      v10 = *(double *)(v13 + 8); 
     v18 = v10; 
     v19 = v9; 
     v20 = v18; 
     if (v19 > *(double *)(v13 + 8)) 
      v19 = *(double *)(v13 + 8); 
     v21 = v19; 
     v10 = v20; 
     v9 = v21; 
     if (v12 < 0) 
      break; 
     if (v10 < *(double *)v13) 
      v10 = *(double *)v13; 
     v22 = v10; 
     v23 = v9; 
     v24 = v22; 
     if (v23 > *(double *)v13) 
      v23 = *(double *)v13; 
     v25 = v23; 
     v10 = v24; 
     v9 = v25; 
     if (v12 - 1 < 0) 
      break; 
     if (v10 < *(double *)(v13 - 8)) 
      v10 = *(double *)(v13 - 8); 
     v26 = v10; 
     v27 = v9; 
     v28 = v26; 
     if (v27 > *(double *)(v13 - 8)) 
      v27 = *(double *)(v13 - 8); 
     v11 += 4; 
     v29 = v27; 
     v10 = v28; 
     v9 = v29; 
     v13 -= 32; 
     v12 -= 4; 
     if (v11 >= a3 - 3) 
      goto LABEL_28; 
     } 
    } 
    v36 = 50; 
    v37 = 0.5; 
    v38 = (v10 + v9) * 0.5; 
    if (v38 - v9 <= 0.005) 
    { 
     result = v38; 
    } 
    else 
    { 
     v39 = 0.0; 
     while (v36 > 0) 
     { 
     v44 = 0; 
     v45 = v39; 
     if (v39 < v6) 
     { 
      v46 = v60; 
      v47 = v8; 
      do 
      { 
      if (v47 < 0) 
       break; 
      v48 = v45; 
      v49 = v38; 
      v50 = v48; 
      if (v49 < *(double *)v46) 
       v39 = v39 + 1.0; 
      ++v44; 
      v46 -= 8; 
      --v47; 
      v51 = v49; 
      v45 = v50; 
      v38 = v51; 
      } 
      while ((double)v44 < v6); 
     } 
     if (a2 - 0.001 <= v39/v6) 
     { 
      v54 = (v38 + v10) * v37; 
      v9 = v38; 
      v55 = v37; 
      v56 = v10; 
      v52 = v55; 
      v57 = v56; 
      v53 = v54; 
      v38 = v57; 
     } 
     else 
     { 
      v52 = v37; 
      v53 = (v38 + v9) * v37; 
     } 
     --v36; 
     if (v53 - v9 <= 0.005) 
      return v53; 
     v6 = v58; 
     v40 = v52; 
     v10 = v38; 
     v41 = v40; 
     v42 = v53; 
     v37 = v41; 
     v43 = v42; 
     v39 = v45; 
     v38 = v43; 
     } 
     result = v38; 
    } 
    } 
    else 
    { 
    result = 2147483647.0; 
    } 
    return result; 
} 

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 

    double *buffer; 
    double Probability; 
    int DzLookBackBars; 
    int Bars; 
    int i; 
    double result; 

    // Check inputs 
    if (nrhs != 5) {//if the user has given anything but one arg, then error 
    mexErrMsgIdAndTxt("Numerical:myGetPr:nrhs", "Require 5 args"); 
    } 
    if (!mxIsNumeric(prhs[0])) {//if input is not numeric (for example a string), then errror 
    mexErrMsgIdAndTxt("Numerical:myGetPr:isnumeric", "Require args that is numeric"); 
    } 

    if(nlhs!=1) { 
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs","One output required."); 
    } 

    /* make sure the first input argument is type double */ 
    if(!mxIsDouble(prhs[0]) || 
     mxIsComplex(prhs[0])) { 
     mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble","Input matrix must be type double."); 
    } 

    // Check output 

     int dims[] = {1,1}; //dimensions of output 

     buffer = mxGetPr(prhs[0]); 
     Probability = mxGetScalar(prhs[1]); 
     DzLookBackBars = mxGetScalar(prhs[2]); 
     Bars = mxGetScalar(prhs[3]); 
     i = mxGetScalar(prhs[4]); 

     result = dzSell ((uintptr_t)buffer, Probability, DzLookBackBars, Bars, i); 

     plhs[0] = mxCreateDoubleScalar(result); 

} 

и здесь экраны, которые не оправдаться литье

enter image description here

любая идея, как бороться с этим ???

пример декомпиляции массивов, Hex-Rays здесь

Hex-Rays decompiles array to int

и здесь РАЗБОРКОЙ файлу

http://www.mediafire.com/view/w82l6somwr7o450/dissasembly.txt

Кшиштоф

+1

Тип 'a1' в списке параметров' dzSell' - 'int'. Поскольку вы намереваетесь использовать 'uintptr_t', возможно, вы должны сделать это вместо этого. Вы также должны изменить все соответствующие значения 'int' в этой функции, которые явно используются для арифметики« указатель ». – paddy

+0

Просто подумайте, вам может быть лучше скомпилировать сборку в объектный файл и связать его. Даже декомпиляторы для интерпретируемых языков могут иметь проблемы, не говоря уже о собственных кодовых. –

+0

да, я изменил тип при определении функции на uintptr_t, и он помог, но имел другую ошибку сегментации в строке if (v10 <* (double *) (v13 + 16)) –

ответ

1

Рассмотрим декомпилятор, как давая вам голова, не создавая хороший код.

В частности, созданный им код совсем не переносится. Чтобы иметь возможность компилировать другой размер указателя, вам нужно будет исправить информацию о типе.

0

Решение заключалось в использовании uintptr_t и intptr_t 64-битного целого числа как в определении функции, так и внутри декомпилированной функции. Декомпилированная dll была из 32-битной системы, но моя функция предположила работать под win 7 64. Я использовал IDA 64 с декомпилятором, но генерация псевдокода была 32 бит.

+0

Ну, действительно, код был бы более читабельным, если бы вы использовали ' double * 'вместо этого. Вы можете избавиться от всех бросков и использовать подтипы массива вместо арифметики указателя. Просто помните, что декомпилированный код добавляет 8 к адресу для каждого элемента, поэтому '* (double *) (p + 8)' совпадает с '((double *) p) [1]' –