@@ -52,12 +52,20 @@ which is a dynamic public symbol that should be in all binaries of LuaJIT includ
5252func (x * x86Extractor ) findOffsetsFromLuaClose (b []byte ) (glref , curL uint64 , err error ) {
5353 b , _ = xh .SkipEndBranch (b )
5454 var greg x86asm.Reg
55+ var zeroReg x86asm.Reg
5556 for len (b ) > 0 {
5657 var i x86asm.Inst
5758 i , err = x86asm .Decode (b , 64 )
5859 if err != nil {
5960 return 0 , 0 , err
6061 }
62+ if i .Op == x86asm .XOR {
63+ a0 , ok1 := i .Args [0 ].(x86asm.Reg )
64+ a1 , ok2 := i .Args [1 ].(x86asm.Reg )
65+ if ok1 && ok2 && a0 == a1 {
66+ zeroReg = a0
67+ }
68+ }
6169 if i .Op == x86asm .MOV {
6270 if greg == 0 {
6371 a0 , ok1 := i .Args [0 ].(x86asm.Reg )
@@ -68,10 +76,17 @@ func (x *x86Extractor) findOffsetsFromLuaClose(b []byte) (glref, curL uint64, er
6876 }
6977 } else {
7078 a0 , ok1 := i .Args [0 ].(x86asm.Mem )
71- a1 , ok2 := i .Args [1 ].(x86asm.Imm )
72- if ok1 && ok2 && sameReg (a0 .Base , greg ) && a1 == 0 {
73- curL = uint64 (a0 .Disp )
74- return glref , curL , nil
79+ if ok1 && sameReg (a0 .Base , greg ) {
80+ imm , ok2 := i .Args [1 ].(x86asm.Imm )
81+ if ok2 && imm == 0 {
82+ curL = uint64 (a0 .Disp )
83+ return glref , curL , nil
84+ }
85+ r1 , ok2 := i .Args [1 ].(x86asm.Reg )
86+ if ok2 && sameReg (r1 , zeroReg ) {
87+ curL = uint64 (a0 .Disp )
88+ return glref , curL , nil
89+ }
7590 }
7691 // If Greg is dest error
7792 if r0 , ok := i .Args [0 ].(x86asm.Reg ); ok && sameReg (r0 , greg ) {
@@ -82,7 +97,7 @@ func (x *x86Extractor) findOffsetsFromLuaClose(b []byte) (glref, curL uint64, er
8297 }
8398 b = b [i .Len :]
8499 }
85- return 0 , 0 , errors .New ("offsets not found " )
100+ return 0 , 0 , errors .New ("find offsets from lua_close failed " )
86101}
87102
88103// This is different in most builds and we need to get it from stripped binaries.
@@ -325,8 +340,10 @@ func findRipRelativeLea2ndArgTo2ndCall(b []byte, baseAddr, targetCall int64) (ui
325340//nolint:gocritic
326341func skipCallsAABA (b []byte , ip , baseAddr int64 ) ([]byte , int64 , error ) {
327342 var lastCall int64
343+ var acall int64
344+ // 3 Step process, 1 is find AA, 2 is find B and 3 is find A.
328345 step := 0
329- for len (b ) > 0 && step < 3 {
346+ for len (b ) > 0 {
330347 i , err := x86asm .Decode (b , 64 )
331348 if err != nil {
332349 return nil , 0 , err
@@ -335,20 +352,29 @@ func skipCallsAABA(b []byte, ip, baseAddr int64) ([]byte, int64, error) {
335352 a0 , ok := i .Args [0 ].(x86asm.Rel )
336353 if ok {
337354 callAddr := baseAddr + ip + int64 (i .Len ) + int64 (a0 )
338- if lastCall == callAddr {
339- // Found AA
340- step ++
341- } else if step > 0 {
342- step ++
355+ if step == 0 && callAddr == lastCall {
356+ // Found potential AA
357+ step = 1
358+ acall = callAddr
359+ } else if step == 1 && callAddr != lastCall {
360+ // Found AAB
361+ step = 2
362+ } else if step == 2 && callAddr == acall {
363+ // Found AABA
364+ step = 3
365+ } else {
366+ // Found different pattern, reset
367+ step = 0
368+ acall = 0
343369 }
344370 lastCall = callAddr
345371 }
346372 }
347373 ip += int64 (i .Len )
348374 b = b [i .Len :]
349- }
350- if step == 3 {
351- return b , ip , nil
375+ if step == 3 {
376+ return b , ip , nil
377+ }
352378 }
353379 return nil , 0 , errors .New ("failed to find AABA call pattern" )
354380}
0 commit comments