【篇首语】这里的逆向分析不是机械中的反求工程(抄数),而是软件中的逆向工程,旨在研究软件内部代码实现机制。我在这里要说明一下,软件逆向不在软件使用的许可范围之内,仅可以作为研究软件实现功能的一种方法。

另外,我不是计算机专业的,软件逆向这种高技术难度的事情我做不到,只是看到论坛上有人发了一个UG的一个函数逆向分析,让我大开眼界,我觉得可以拿出来让大家也开开眼界!

本文仅是转载帖子,不承担责任,有什么问题请联系原作者!本贴仅作研究之用!

原帖:http://hi.baidu.com/xusir98/blog/item/269d9eaf17860ac07dd92a77.html

作者:xusir98

===================================================================

注: 按F5 快捷健是IDA 一个很好用的插件功能, 能大大减少逆向程序员的工作强度,

但是对于一些复杂的逻辑处理的还是不很好

extern void UF_MTX3_rotate_about_axis (
const double rotation_axis[ 3 ],
double rotation_angle,
double mtx[ 9 ] );

const double

rotation_axis[ 3 ]

Input

Vector of the rotation axis

double

rotation_angle

Input

Angle of the rotation (in radians)

double

mtx[ 9 ]

Output

Rotation Matrix

UF_MTX3_rotate_about_axis 是UgOpen 里的一个输出旋转矩阵的函数,

他输入一个旋转轴, 一个角度, 输出一个旋转用的3 维矩阵

用 IDA 打开 libufun.dll

找到 UF_MTX3_rotate_about_axis

经更改调用函数参数显示如下 :

; int __cdecl UF_MTX3_rotate_about_axis(int rotation_axis, double rotation_angle, int mtx)

public _UF_MTX3_rotate_about_axis

_UF_MTX3_rotate_about_axis proc near    ; DATA XREF: .rdata:off_1033A6E8o

var_10= qword ptr -10h

rotation_axis= dword ptr  8

rotation_angle= qword ptr  0Ch

mtx = dword ptr  14h

push ebp

mov ebp, esp

mov eax, [ebp+mtx]

fld [ebp+rotation_angle]                ; 把传进来的参数放入 st0 中

mov ecx, [ebp+rotation_axis]

push eax

push ecx

sub esp, 8                           ; 抬高栈 8 个字节

fstp [esp+10h+var_10]                 ; 将 st0 的值放入抬高栈的空间里

; const double rotation_axis[ 3 ],

; double rotation_angle,

; double mtx[ 9 ] )

call ds:__imp_?MTX3_rot_about_axis@@YAXNPBUVEC3_s@@PAUMTX3_s@@@Z ;

; 调用 NX 内核函数

; 注意参数位置调换过

add esp, 10h                          ; c 调用约定 , 将栈降低 16 个字节

pop ebp

retn

_UF_MTX3_rotate_about_axis endp

按下 F5 显示如下

void __cdecl UF_MTX3_rotate_about_axis(const struct VEC3_s *rotation_axis, double rotation_angle, struct MTX3_s *mtx)

{

MTX3_rot_about_axis(rotation_angle, rotation_axis, mtx);

}

可见 UF_MTX3_rotate_about_axis 调用了 MTX3_rot_about_axis, 并且把参数的位置更改变化了

MTX3_rot_about_axis 这个函数在 libugmath.dll 里

同样用 IDA 打开 libugmath.dll

找到 MTX3_rot_about_axis 函数

显示如下 :

; void __cdecl MTX3_rot_about_axis(double rotation_angle, double *rotation_axis, const struct MTX3_s *mtx)

public ?MTX3_rot_about_axis@@YAXNPBUVEC3_s@@PAUMTX3_s@@@Z

?MTX3_rot_about_axis@@YAXNPBUVEC3_s@@PAUMTX3_s@@@Z proc near

; CODE XREF: ARC_SPLINE_ask_bisector_of_inscribed_angle(VEC3_s *,VEC3_s *,PNT3_s *,VEC3_s *,double,double *,double *,int *,VEC3_s *,PLN3_s *)+169p

; ARC_SPLINE_cre_matrix_of_rotation_around_axis(VEC3_s *,double,MTX3_s *)+1Ap ...

var_30= qword ptr -30h

var_28= qword ptr -28h

unit_vec= qword ptr -20h

magnitude= qword ptr -8

rotation_angle= qword ptr  8

rotation_axis= dword ptr  10h

mtx = dword ptr  14h

push ebp

mov ebp, esp

sub esp, 20h

fld ds:__real@3ddb7cdfd9d7bdbb       ; 参数 2, 压入 st0

mov edx, [ebp+rotation_axis]

lea eax, [ebp+unit_vec]

push eax                            ; 参数 4

lea ecx, [ebp-8]

push ecx                            ; 参数 3

sub esp, 8

fstp [esp+30h+var_30]                 ; 参数 2, 从 st0 弹出

push edx                            ; 参数 1

call ?VEC3_unitize@@YAHPBUVEC3_s@@NPANPAU1@@Z ; VEC3_unitize(VEC3_s const *,double,double *,VEC3_s *)

add esp, 14h

test eax, eax

jz  short loc_201CBCB6

fld [ebp+rotation_angle]

fsin

fld [ebp+rotation_angle]

fcos

jmp short loc_201CBCC2

; ---------------------------------------------------------------------------

loc_201CBCB6:                           ; CODE XREF: MTX3_rot_about_axis(double,VEC3_s const *,MTX3_s *)+28j

fld ds:__real@0000000000000000

fld ds:__real@3ff0000000000000

loc_201CBCC2:                           ; CODE XREF: MTX3_rot_about_axis(double,VEC3_s const *,MTX3_s *)+34j

mov eax, [ebp+mtx]                  ; EAX

fxch st(1)

sub esp, 10h

fstp [esp+30h+var_28]

lea ecx, [ebp+unit_vec]             ; ECX

fstp [esp+30h+var_30]

call sub_201CB3C0

add esp, 10h

mov esp, ebp

pop ebp

retn

?MTX3_rot_about_axis@@YAXNPBUVEC3_s@@PAUMTX3_s@@@Z endp

按下 F5 显示如下 :

void __cdecl MTX3_rot_about_axis(double rotation_angle, double *rotation_axis, const struct MTX3_s *mtx)

{

double fCos; // st6@2

double fSin; // st7@2

double unit_vec[3]; // [sp+10h] [bp-20h]@1

double magnitude; // [sp+28h] [bp-8h]@1

if ( VEC3_unitize(rotation_axis, 1.0e-10, &magnitude, unit_vec) )

{

fSin = sin(rotation_angle);

fCos = cos(rotation_angle);

}

else

{

fSin = 0.0;

fCos = 1.0;

}

sub_201CB3C0(mtx, unit_vec, fCos, fSin);

}

可见他先调用 VEC3_unitize 函数看看输入的矢量是否是初始话的 , 如果初始化失败 , 就

fSin = 0.0;

fCos = 1.0;

然后调用 sub_201CB3C0 这个子函数

分析 VEC3_unitize 函数

; int __cdecl VEC3_unitize(double *rotation_axis, double a2, double *magnitude, double *unit_vec)

public ?VEC3_unitize@@YAHPBUVEC3_s@@NPANPAU1@@Z

?VEC3_unitize@@YAHPBUVEC3_s@@NPANPAU1@@Z proc near

; CODE XREF: ARC_SPLINE_ask_3pts_collinearity_3d(PNT3_s *,PNT3_s *,PNT3_s *,double *,int *)+D5p

; ARC_SPLINE_adjust_vec_on_pln(uchar,VEC3_s *,VEC3_s *)+44p ...

var_8= qword ptr -8

rotation_axis= dword ptr  8

a2  = qword ptr  0Ch

magnitude= dword ptr  14h

unit_vec= dword ptr  18h

push ebp

mov ebp, esp

sub esp, 8

mov eax, ds:__imp_?MACH__checking_level@@3HA ; int MACH__checking_level

cmp dword ptr [eax], 0

push esi

mov esi, [ebp+rotation_axis]

jle short loc_201DB4EE

fld qword ptr [esi]

fabs

fcomp ds:__real@43e158e460913d00

fnstsw ax

test ah, 5

jp  short loc_201DB4D9

fld qword ptr [esi+8]

fabs

fcomp ds:__real@43e158e460913d00

fnstsw ax

test ah, 5

jp  short loc_201DB4D9

fld qword ptr [esi+10h]

fabs

fcomp ds:__real@43e158e460913d00

fnstsw ax

test ah, 5

jnp short loc_201DB4EE

loc_201DB4D9:                            ; CODE XREF: VEC3_unitize(VEC3_s const *,double,double *,VEC3_s *)+23j

; VEC3_unitize(VEC3_s const *,double,double *,VEC3_s *)+35j

push offset aVec3_is_finite         ; "VEC3_is_finite (u)"

push 44h

push offset aDUgnx30Sand_16         ; "D://ugnx30//sandbox//src//ugmath//no//ind//vec"...

call ds:__imp_?ERROR_assertion_failed@@YAXPBDH0@Z ; ERROR_assertion_failed(char const *,int,char const *)

add esp, 0Ch

loc_201DB4EE:                            ; CODE XREF: VEC3_unitize(VEC3_s const *,double,double *,VEC3_s *)+12j

; VEC3_unitize(VEC3_s const *,double,double *,VEC3_s *)+47j

fld qword ptr [esi+10h]

fld qword ptr [esi+8]

fld qword ptr [esi]

fld st

fmul st, st(1)

fstp [ebp+var_8]

fstp st

fld st

fmul st, st(1)

fld st(2)

fmul st, st(3)

faddp st(1), st

fadd [ebp+var_8]

fabs

fld [ebp+a2]

fmul [ebp+a2]

fcompp

fnstsw ax

fstp st

test ah, 1

fstp st

jz  short loc_201DB568

fld qword ptr [esi+10h]

mov ecx, [ebp+magnitude]

fld qword ptr [esi+8]

mov eax, 1

fld st

fmul st, st(1)

fld st(2)

fmul st, st(3)

faddp st(1), st

fadd [ebp+var_8]

fsqrt

fstp st(2)

fstp st

fld st

fstp qword ptr [ecx]

mov ecx, [ebp+unit_vec]

fdivr ds:__real@3ff0000000000000

fld st

fmul qword ptr [esi]

fstp qword ptr [ecx]

fld st

fmul qword ptr [esi+8]

fstp qword ptr [ecx+8]

fmul qword ptr [esi+10h]

pop esi

fstp qword ptr [ecx+10h]

mov esp, ebp

pop ebp

retn

; ---------------------------------------------------------------------------

loc_201DB568:                           ; CODE XREF: VEC3_unitize(VEC3_s const *,double,double *,VEC3_s *)+8Fj

fld ds:__real@0000000000000000

mov edx, [ebp+magnitude]

mov ecx, [ebp+unit_vec]

fstp qword ptr [edx]

fld ds:__real@0000000000000000

xor eax, eax

fstp qword ptr [ecx]

pop esi

fld ds:__real@0000000000000000

fstp qword ptr [ecx+8]

fld ds:__real@0000000000000000

fstp qword ptr [ecx+10h]

mov esp, ebp

pop ebp

retn

?VEC3_unitize@@YAHPBUVEC3_s@@NPANPAU1@@Z endp

F5 后有 :

int __cdecl VEC3_unitize(double *rotation_axis, double a2, double *magnitude, double *unit_vec)

{

int result; // eax@7

double v5; // st5@7

double v6; // [sp+4h] [bp-8h]@6

if ( MACH__checking_level > 0 )

{

if ( fabs(*rotation_axis) >= 1.0e19 || fabs(rotation_axis[1]) >= 1.0e19 || fabs(rotation_axis[2]) >= 1.0e19 )

ERROR_assertion_failed("D://ugnx30//sandbox//src//ugmath//no//ind//vec3.c", 68, "VEC3_is_finite (u)");

}

v6 = *rotation_axis * *rotation_axis;

if ( a2 * a2 >= fabs(rotation_axis[1] * rotation_axis[1] + rotation_axis[2] * rotation_axis[2] + v6) )

{                                             // 如果矢量的平方和接近与 0, 就返回错误

*magnitude = 0.0;

result = 0;

*unit_vec = 0.0;

unit_vec[1] = 0.0;

unit_vec[2] = 0.0;

}

else

{

result = 1;

v5 = sqrt(rotation_axis[1] * rotation_axis[1] + rotation_axis[2] * rotation_axis[2] + v6);

*(_QWORD *)magnitude = *(_QWORD *)&v5;

*unit_vec = 1.0 / v5 * *rotation_axis;

unit_vec[1] = 1.0 / v5 * rotation_axis[1];

unit_vec[2] = 1.0 / v5 * rotation_axis[2];

}

return result;

}

他做的工作是如果矢量的平方和接近与 0, 就返回错误 , 否则就返回一个模化好的矢量

if ( MACH__checking_level > 0 )

{

if ( fabs(*rotation_axis) >= 1.0e19 || fabs(rotation_axis[1]) >= 1.0e19 || fabs(rotation_axis[2]) >= 1.0e19 )

ERROR_assertion_failed("D://ugnx30//sandbox//src//ugmath//no//ind//vec3.c", 68, "VEC3_is_finite (u)");

}

的意思是当机器的检测权限大于 0 时 , 就报出诊断错误

接下来就看看 sub_201CB3C0 这个子函数到底做了些什么吧 !

这个子函数是我逆向最久的一个函数 , 因为这个函数按 F5 实效了 , 于是我把浮点的栈一句一句的模拟出来

最后得出公式 :

; void __usercall sub_201CB3C0(const struct MTX3_s *EAX<eax>, double *ECX<ecx>, double fCos, double fSin)

sub_201CB3C0 proc near                  ; CODE XREF: MTX3_rot_about_axis(double,VEC3_s const *,MTX3_s *)+54p

var_20= qword ptr -20h

var_18= qword ptr -18h

var_10= qword ptr -10h

var_8= qword ptr -8

fCos= qword ptr  8

fSin= qword ptr  10h

push ebp

mov ebp, esp                        ; (eax->mtx, ecx->unit_vec, fCos, fSin)

sub esp, 20h

fld qword ptr [ecx]                 ; ecx[0]

fld qword ptr [ecx+8]               ; ecx[1]

fld qword ptr [ecx+10h]             ; ecx[2]

fld ds:__real@3ff0000000000000      ; st0:1

; st1:ecx[2]

; st2:ecx[1]

; st3:ecx[0]

; st4:

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fsub [ebp+fCos]                     ; st0:1-fCos

; st1:ecx[2]

; st2:ecx[1]

; st3:ecx[0]

; st4:

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fld st                              ; st0:1-fCos

; st1:1-fCos

; st2:ecx[2]

; st3:ecx[1]

; st4:ecx[0]

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fmul st, st(4)                      ; st0:(1-fCos)*ecx[0]

; st1:1-fCos

; st2:ecx[2]

; st3:ecx[1]

; st4:ecx[0]

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fld st(1)                           ; st0:1-fCos

; st1:(1-fCos)*ecx[0]

; st2:1-fCos

; st3:ecx[2]

; st4:ecx[1]

; st5:ecx[0]

; st6:

; st7:

; ~~~~~~~~~~~~

fmul st, st(4)                      ; st0:(1-fCos)*ecx[1]

; st1:(1-fCos)*ecx[0]

; st2:1-fCos

; st3:ecx[2]

; st4:ecx[1]

; st5:ecx[0]

; st6:

; st7:

; ~~~~~~~~~~~~

fld st(1)                            ; st0:(1-fCos)*ecx[0]

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fmul st, st(5)                       ; st0:(1-fCos)*ecx[0]*ecx[1]

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fld st(2)                            ; st0:(1-fCos)*ecx[0]

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:(1-fCos)*ecx[1]

; st3:(1-fCos)*ecx[0]

; st4:1-fCos

; st5:ecx[2]

; st6:ecx[1]

; st7:ecx[0]

; ~~~~~~~~~~~~

fmul st, st(5)                       ; st0:(1-fCos)*ecx[0]*ecx[2]

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:(1-fCos)*ecx[1]

; st3:(1-fCos)*ecx[0]

; st4:1-fCos

; st5:ecx[2]

; st6:ecx[1]

; st7:ecx[0]

; ~~~~~~~~~~~~

fstp [ebp+var_8]                    ; var_8=(1-fCos)*ecx[0]*ecx[2]

; st0:(1-fCos)*ecx[0]*ecx[1]

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fld st(1)                           ; st0:(1-fCos)*ecx[1]

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:(1-fCos)*ecx[1]

; st3:(1-fCos)*ecx[0]

; st4:1-fCos

; st5:ecx[2]

; st6:ecx[1]

; st7:ecx[0]

; ~~~~~~~~~~~~

fmul st, st(5)                      ; st0:(1-fCos)*ecx[1]*ecx[2]

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:(1-fCos)*ecx[1]

; st3:(1-fCos)*ecx[0]

; st4:1-fCos

; st5:ecx[2]

; st6:ecx[1]

; st7:ecx[0]

; ~~~~~~~~~~~~

fstp [ebp+var_20]                   ; var_20 = (1-fCos)*ecx[1]*ecx[2]

; st0:(1-fCos)*ecx[0]*ecx[1]

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fld st(6)                           ; st0:ecx[0]

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:(1-fCos)*ecx[1]

; st3:(1-fCos)*ecx[0]

; st4:1-fCos

; st5:ecx[2]

; st6:ecx[1]

; st7:ecx[0]

; ~~~~~~~~~~~~

fmul [ebp+fSin]                     ; st0:ecx[0]*fSin

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:(1-fCos)*ecx[1]

; st3:(1-fCos)*ecx[0]

; st4:1-fCos

; st5:ecx[2]

; st6:ecx[1]

; st7:ecx[0]

; ~~~~~~~~~~~~

fstp [ebp+var_18]                   ; var_18 = ecx[0]*fsin

; st0:(1-fCos)*ecx[0]*ecx[1]

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fld st(5)                            ; st0:ecx[1]

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:(1-fCos)*ecx[1]

; st3:(1-fCos)*ecx[0]

; st4:1-fCos

; st5:ecx[2]

; st6:ecx[1]

; st7:ecx[0]

; ~~~~~~~~~~~~

fmul [ebp+fSin]                      ; st0:ecx[1]*fSin

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:(1-fCos)*ecx[1]

; st3:(1-fCos)*ecx[0]

; st4:1-fCos

; st5:ecx[2]

; st6:ecx[1]

; st7:ecx[0]

; ~~~~~~~~~~~~

fstp [ebp+var_10]                    ; var_10 = ecx[1]*fsin

; st0:(1-fCos)*ecx[0]*ecx[1]

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fld st(4)                           ; st0:ecx[2]

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:(1-fCos)*ecx[1]

; st3:(1-fCos)*ecx[0]

; st4:1-fCos

; st5:ecx[2]

; st6:ecx[1]

; st7:ecx[0]

; ~~~~~~~~~~~~

fmul [ebp+fSin]                     ; st0:ecx[2]*fSin

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:(1-fCos)*ecx[1]

; st3:(1-fCos)*ecx[0]

; st4:1-fCos

; st5:ecx[2]

; st6:ecx[1]

; st7:ecx[0]

; ~~~~~~~~~~~~

fstp [ebp+fSin]                     ; fSin = ecx[2]*fSin

; st0:(1-fCos)*ecx[0]*ecx[1]

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fxch st(2)                          ; st0:(1-fCos)*ecx[0]

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]*ecx[1]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fmul st, st(6)                      ; st0:(1-fCos)*ecx[0]*ecx[0]

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]*ecx[1]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fadd [ebp+fCos]                     ; st0:(1-fCos)*ecx[0]*ecx[0]+fCos

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]*ecx[1]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fstp qword ptr [eax]                ; eax[0] = (1-fCos)*ecx[0]*ecx[0]+fCos

; st0:(1-fCos)*ecx[1]

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:1-fCos

; st3:ecx[2]

; st4:ecx[1]

; st5:ecx[0]

; st6:

; st7:

; ~~~~~~~~~~~~

fld [ebp+fSin]                      ; st0:ecx[2]*fSin

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]*ecx[1]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fsubr st, st(2)                     ; st0:(1-fCos)*ecx[0]*ecx[1] - ecx[2]*fSin

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]*ecx[1]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fstp qword ptr [eax+8]              ; eax[1] = (1-fCos)*ecx[0]*ecx[1] - ecx[2]*fSin

; st0:(1-fCos)*ecx[1]

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:1-fCos

; st3:ecx[2]

; st4:ecx[1]

; st5:ecx[0]

; st6:

; st7:

; ~~~~~~~~~~~~

fld [ebp+var_10]                     ; st0:ecx[1]*fsin

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]*ecx[1]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fadd [ebp+var_8]                     ; st0:ecx[1]*fsin+(1-fCos)*ecx[0]*ecx[2]

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]*ecx[1]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fstp qword ptr [eax+10h]            ; eax[2] = (1-fCos)*ecx[0]*ecx[2] + ecx[1]*fsin

; st0:(1-fCos)*ecx[1]

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:1-fCos

; st3:ecx[2]

; st4:ecx[1]

; st5:ecx[0]

; st6:

; st7:

; ~~~~~~~~~~~~

fld [ebp+fSin]                      ; st0:ecx[2]*fSin

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]*ecx[1]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fadd st, st(2)                      ; st0:ecx[2]*fSin + (1-fCos)*ecx[0]*ecx[1]

; st1:(1-fCos)*ecx[1]

; st2:(1-fCos)*ecx[0]*ecx[1]

; st3:1-fCos

; st4:ecx[2]

; st5:ecx[1]

; st6:ecx[0]

; st7:

; ~~~~~~~~~~~~

fstp qword ptr [eax+18h]            ; eax[3] = (1-fCos)*ecx[0]*ecx[1] + ecx[2]*fSin

; st0:(1-fCos)*ecx[1]

; st1:(1-fCos)*ecx[0]*ecx[1]

; st2:1-fCos

; st3:ecx[2]

; st4:ecx[1]

; st5:ecx[0]

; st6:

; st7:

; ~~~~~~~~~~~~

fstp st(1)                          ; st0:(1-fCos)*ecx[1]

; st1:1-fCos

; st2:ecx[2]

; st3:ecx[1]

; st4:ecx[0]

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fmul st, st(3)                      ; st0:(1-fCos)*ecx[1]*ecx[1]

; st1:1-fCos

; st2:ecx[2]

; st3:ecx[1]

; st4:ecx[0]

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fadd [ebp+fCos]                     ; st0:(1-fCos)*ecx[1]*ecx[1]+fCos

; st1:1-fCos

; st2:ecx[2]

; st3:ecx[1]

; st4:ecx[0]

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fstp qword ptr [eax+20h]            ; eax[4] = (1-fCos)*ecx[1]*ecx[1] + fCos

; st0:1-fCos

; st1:ecx[2]

; st2:ecx[1]

; st3:ecx[0]

; st4:

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fld [ebp+var_20]                    ; st0:(1-fCos)*ecx[1]*ecx[2]

; st1:1-fCos

; st2:ecx[2]

; st3:ecx[1]

; st4:ecx[0]

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fsub [ebp+var_18]                   ; st0:(1-fCos)*ecx[1]*ecx[2]-ecx[0]*fsin

; st1:1-fCos

; st2:ecx[2]

; st3:ecx[1]

; st4:ecx[0]

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fstp qword ptr [eax+28h]            ; eax[5] = (1-fCos)*ecx[1]*ecx[2] - ecx[0]*fsin

; st0:1-fCos

; st1:ecx[2]

; st2:ecx[1]

; st3:ecx[0]

; st4:

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fld [ebp+var_8]                     ; st0:(1-fCos)*ecx[0]*ecx[2]

; st1:1-fCos

; st2:ecx[2]

; st3:ecx[1]

; st4:ecx[0]

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fsub [ebp+var_10]                    ; st0:(1-fCos)*ecx[0]*ecx[2]-ecx[1]*fsin

; st1:1-fCos

; st2:ecx[2]

; st3:ecx[1]

; st4:ecx[0]

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fstp qword ptr [eax+30h]            ; eax[6] = (1-fCos)*ecx[0]*ecx[2] - ecx[1]*fsin

; st0:1-fCos

; st1:ecx[2]

; st2:ecx[1]

; st3:ecx[0]

; st4:

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fld [ebp+var_18]                    ; st0:ecx[0]*fsin

; st1:1-fCos

; st2:ecx[2]

; st3:ecx[1]

; st4:ecx[0]

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fadd [ebp+var_20]                   ; st0:ecx[0]*fsin+(1-fCos)*ecx[1]*ecx[2]

; st1:1-fCos

; st2:ecx[2]

; st3:ecx[1]

; st4:ecx[0]

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fstp qword ptr [eax+38h]            ; eax[7] = (1-fCos)*ecx[1]*ecx[2] + ecx[0]*fsin

; st0:1-fCos

; st1:ecx[2]

; st2:ecx[1]

; st3:ecx[0]

; st4:

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fmul st, st(1)

fmul st, st(1)                       ; st0:(1-fCos)*ecx[2]*ecx[2]

; st1:ecx[2]

; st2:ecx[1]

; st3:ecx[0]

; st4:

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fadd [ebp+fCos]                     ; st0:(1-fCos)*ecx[2]*ecx[2]+fCos

; st1:ecx[2]

; st2:ecx[1]

; st3:ecx[0]

; st4:

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

fstp qword ptr [eax+40h]            ; eax[8] = (1-fCos)*ecx[2]*ecx[2] + fCos

; st1:ecx[2]

; st2:ecx[1]

; st3:ecx[0]

; st4:

; st5:

; st6:

; st7:

; ~~~~~~~~~~~~

mov ecx, ds:__imp_?MACH__checking_level@@3HA ; int MACH__checking_level

cmp dword ptr [ecx], 0

fstp st

fstp st

fstp st

jle short loc_201CB490

push eax                            ; struct MTX3_s *

call ?MTX3_is_ortho_normal@@YAEPBUMTX3_s@@@Z ; MTX3_is_ortho_normal(MTX3_s const *)

add esp, 4

test al, al

jnz short loc_201CB490

push offset aMtx3_is_ortho_         ; "MTX3_is_ortho_normal (r)"

push 1A9h

push offset aDUgnx30Sand_18         ; "D://ugnx30//sandbox//src//ugmath//no//ind//mtx"...

call ds:__imp_?ERROR_assertion_failed@@YAXPBDH0@Z ; ERROR_assertion_failed(char const *,int,char const *)

add esp, 0Ch

loc_201CB490:                           ; CODE XREF: sub_201CB3C0+A9j

; sub_201CB3C0+B6j

mov esp, ebp

pop ebp

retn

sub_201CB3C0 endp

他是用 eax,ecx 这两个寄存器传参的

; (eax->mtx, ecx->unit_vec, fCos, fSin)

Eax 传的是矩阵的指针 ,ecx 传的是矢量的指针 , 后两个参数是由角度算出的 sin 和 cos 值

最后整理成公式 :

eax[0] = (1-fCos)*ecx[0]*ecx[0] + fCos

eax[1] = (1-fCos)*ecx[0]*ecx[1] - ecx[2]*fSin

eax[2] = (1-fCos)*ecx[0]*ecx[2] + ecx[1]*fsin

eax[3] = (1-fCos)*ecx[0]*ecx[1] + ecx[2]*fSin

eax[4] = (1-fCos)*ecx[1]*ecx[1] + fCos

eax[5] = (1-fCos)*ecx[1]*ecx[2] - ecx[0]*fsin

eax[6] = (1-fCos)*ecx[0]*ecx[2] - ecx[1]*fsin

eax[7] = (1-fCos)*ecx[1]*ecx[2] + ecx[0]*fsin

eax[8] = (1-fCos)*ecx[2]*ecx[2] + fCos

这个就是转换的 3*3 矩阵公式

我用的是 NX3.0, 每次只要旋转图形时 , 他都会到这里来走一堂的 , 呵呵 !

这里是我在网上找到的一篇文章

3D 空间中的旋转可用旋转矩阵、欧拉角或四元数等形式来表示,他们不过都是数学工具,其中在绕任意向量的旋转方面,旋转矩阵和四元数两种工具用的较多,欧拉角由于存在万向节死锁等问题,使用存在限制。

(本文假设坐标系为左手坐标系中,旋转方向为顺时针。)

所求问题:

给定任意单位轴 q(q1,q2,q3)( 向量 ), 求向量 p(x,y,z)( 或点 p) 饶 q 旋转 theta 角度的变换后的新向量 p'( 或点 p') :

1. 用四元数工具:

-------------------------------------------------------------------------

结论:构造四元数变换 p'= q*p*q-1 ,( p,q 是由向量 p,q 扩展成的四元数)。那么, p' 转换至对应的向量 ( 或点 ) 就是变换后的新向量 p'( 或点 p') 。

其中, p',q,p,q-1 均为四元数。 q 由向量 q 扩展 , 为 q=(cos(theta/2),sin(theta/2)*q) , p 由向量 p 扩展 , 为 p=(0,x,y,z),q-1 为 q 的逆,因为 q 为单位四元数,所以 q-1=q*=(cos(theta/2),-sin(theta/2)*q) 。

-------------------------------------------------------------------------

(这个结论的证明过程可以在网上找到。这里略去。)

下面看其时间复杂度:

首先有个三角函数的计算时间,这个可以预先计算好,花费时间不计。考虑 n 个四元数相乘需进行 4*4*(n-1)=16*(n-1) 次乘法, 15*(n-1) 次加法,因为加法化费时间较少,这里仅考虑乘法。这里涉及到三个四元数的乘法,设一次乘法的时间为 T, 故花费 16*2=32T

2. 旋转矩阵工具:

-------------------------------------------------------------------------

结论:构造旋转矩阵变换 Trot, 则变换后的新向量 p'( 或点 p') 为 p'= p*Trot

其中, p' ( x',y',z',1 ) ,p(x,y,z,1) 为向量 p' , p 的 4D 齐次坐标表示, Trot =

|t*q1*q1 + c,           t*q1*q2 + s*q3,       t*q1*q3 - s*q2,      0|

|t*q1*q2 - s*q3,        t*q2*q2 + c,          t*q2*q3 + s*q1,      0|

|t*q1*q3 + s*q2,        t*q2*q3 - s*q1,       t*q3*q3 + c,         0|

|0,                     0,                    0,                   1|

c=cos(theta), s=sin(theta),t=1-c.

-------------------------------------------------------------------------

(这个结论的证明过程可以在网上找到。这里略去。)

下面看其时间复杂度:

三角函数的计算时间不计。矩阵本身的元素乘法主要是计算 t*x 和 s*x 之类,需进行 12+3=15 次乘法。两个矩阵相乘的需进行 n*n*n 次乘法 , 这里 n=4 ,所以花费 4*4*4=64 次乘法时间 , 但这里有个注意的地方就是旋转矩阵的第 4 维无须考虑,即可简化为 3X3 的矩阵。故花费 3*3*3=27 次乘法时间,总共的时间为 15+27=42 次乘法时间。 cost=42T.

比较来看,还是使用四元数的效率要高出一些,这在要变换的点的数目越大时,体现的越明显。实际上,有很多 3D 引擎为了利用四元数运算的高效率性,一般先将矩阵转换成四元数后进行运算再转回为矩阵后,再传给 DirectX 或 OpenGL 库函数。

关于四元数和矩阵在向量(方向)之间的进行插值的效率比较,未完待续。

本文来自 CSDN 博客,转载请标明出处: http://blog.csdn.net/xueyong1203/archive/2007/02/14/1510022.aspx

整理成公式

f9[0] = t*q1*q1 + c;

f9[1] = t*q1*q2 + s*q3;

f9[2] = t*q1*q3 - s*q2;

f9[3] = t*q1*q2 - s*q3;

f9[4] = t*q2*q2 + c;

f9[5] = t*q2*q3 + s*q1;

f9[6] = t*q1*q3 + s*q2;

f9[7] = t*q2*q3 - s*q1;

f9[8] = t*q3*q3 + c;

eax[0] = (1-fCos)*ecx[0]*ecx[0] + fCos

eax[1] = (1-fCos)*ecx[0]*ecx[1] - ecx[2]*fSin

eax[2] = (1-fCos)*ecx[0]*ecx[2] + ecx[1]*fsin

eax[3] = (1-fCos)*ecx[0]*ecx[1] + ecx[2]*fSin

eax[4] = (1-fCos)*ecx[1]*ecx[1] + fCos

eax[5] = (1-fCos)*ecx[1]*ecx[2] - ecx[0]*fsin

eax[6] = (1-fCos)*ecx[0]*ecx[2] - ecx[1]*fsin

eax[7] = (1-fCos)*ecx[1]*ecx[2] + ecx[0]*fsin

eax[8] = (1-fCos)*ecx[2]*ecx[2] + fCos

发现有的地方符号正好相反 , 后来经研究发现他假设的是 坐标系为左手坐标系中,旋转方向为顺时针

而我们的 NX 是右手坐标系 , 所以计算矩阵的算法还是有区别的

2010.05.10 by xusir98

Simens NX (原UG)内部代码逆向分析 / Inner code Reverse analysis of NX software相关推荐

  1. c语言程序怎么还原回代码,逆向分析:如何一步步还原C代码

    逆向实战 应各位的建议,加了注释,喜欢的看官点个赞支持一下,哈哈! 程序入口 如何查找程序入口? main 函数被调用前要先调用的函数如下: GetVersion() _heap_init() Get ...

  2. android qq群加群代码,逆向分析某QQ恶意自动邀请加群APK

    本帖最后由 boomsoap 于 2019-5-23 18:48 编辑 一:基本原理 APK通过调用了qq登陆并实现了使用者的QQ群的读取,让使用者自动的邀请指定的QQ号,而指定QQ号再进行群发消息传 ...

  3. 玩转代码|逆向分析一下4399小游戏绕过实名认证

    4399的实名认证真是越来越恶心了,本以为只是响应国家号召做点表面功夫,没想到现在他们又在网页上加了反调试.看来是4399是认真的. 目录 0X00实名认证提醒 0X01分析 0X03断点发现=关键元 ...

  4. 知物由学 | 干货!一文了解安卓APP逆向分析与保护机制

    "知物由学"是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道."知物 ...

  5. 某K字头运动软件逆向分析-登录时非法的请求

    ​最近重新燃起了运动的热情,经常使用到一款软件,里面有些内容需要付费观看,所以决定给它一些特殊的关爱. 重新打包是避不开的,现在大多app都会做防护,所以决定什么都不做只是反编译重打包试下,果然重打包 ...

  6. 代码保护软件VMP逆向分析虚拟机指令

    VMProtect是一种很可靠的工具,可以保护应用程序代码免受分析和破解,但只有在应用程序内保护机制正确构建且没有可能破坏整个保护的严重错误的情况下,才能实现最好的效果. VMProtect通过在具有 ...

  7. 微信视频号逆向分析+核心爬虫代码

    基于微信7.0.12版本,请自寻下载对应微信版本.打开jadx反编译工具自行比对,主要怕你以为我骗你.至于这个爬虫代码如何运行,请关注我的逆向工作台hooker项目:https://github.co ...

  8. asp.net webform 复制窗体代码_逆向分析流氓软件自我复制以及防御思路

    一.前言 好长时间没有投稿了,之前被发布的稿件,也收到了Freebuf的现金奖励,同时陆陆续续收到好多圈类人士的夸奖,备受鼓舞,觉得自己应该坚持投稿,为安全事业略尽绵薄之力!最近任务不重,正好有时间投 ...

  9. 逆向分析使用COM组件对象模型的代码

    <恶意代码分析实战>第七章实验7-2的程序使用了COM进行联网通信.首先把书上第七章关于COM介绍的原文贴出来: 总结一下,就是说恶意程序有时会通过另一个服务程序提供的接口函数实现一些操作 ...

最新文章

  1. sqlserver mysql 乱码_SQLServer数据库如何解决中文乱码问题?方法有哪些?
  2. python表单提交的两种方式_详解flask表单提交的两种方式
  3. C#.NET 通用权限管理系统组件 大数据多表分页获取部分列的参考方法
  4. AB1601编译优化参数引发的问题
  5. Struts2-从值栈获取list集合数据(三种方式)
  6. 使用list和tuple
  7. Longest k-Good Segment CodeForces - 616D(尺取法)
  8. Mysql学习总结(46)——8种常被忽视的SQL错误用法
  9. 安装 pear、phpunit 测试用例步骤方法
  10. MyBatis映射文件6
  11. Transformers Assemble(PART IV)
  12. php 瓶颈,使用XHProf查找PHP性能瓶颈
  13. icesat/glas与SRTM参考椭球、基准对比
  14. java 从socket读数据,从数据读取TcpClient不如socket
  15. 爬虫案例——模拟登录QQ空间
  16. mysql jdbc密码密文_druid配置数据库连接使用密文密码
  17. 编写程序输入年利率k(例如2.52%),存款总额total(例如100000元),计算一年后的本息并输出。
  18. float及float浮动坍塌问题
  19. OpenCV读取图片
  20. Unity Profiler

热门文章

  1. 微信小程序聊天功能(可以发文字和图片,不能发视频)
  2. 「Rust笔记」Rust之自定义宏写法
  3. 米推(MiPush)简述
  4. Introduce·传播学重点核心期刊推荐之《中国编辑》
  5. 七月算法机器学习笔记10 人工神经网络
  6. 最详细的“ECC-汉明码”原理讲解
  7. 橡皮筋CRectTracker使用心得
  8. 中外双会场 | 中国大连英国利兹同步召开 | 多年稳定快速检索 | EI学术会议征稿啦!!!
  9. UMOUNT NAS报错No space left on device和was not found in /proc/mounts
  10. 高效办公+智慧生活:科大讯飞发布四款消费类新品