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

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

另外,我不是计算机专业的,软件逆向这种高技术难度的事情我做不到,只是看到论坛上有人发了一个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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值