Skip to content

Fix ea pattern - #26

Open
Mr-Pine wants to merge 7 commits into
fmlab-iis:masterfrom
Mr-Pine:fix-ea-pattern
Open

Fix ea pattern#26
Mr-Pine wants to merge 7 commits into
fmlab-iis:masterfrom
Mr-Pine:fix-ea-pattern

Conversation

@Mr-Pine

@Mr-Pine Mr-Pine commented Aug 7, 2026

Copy link
Copy Markdown

#21 changed the format of effective address variables. This PR fixes the pattern in to_zdsl.py such that rules containing $1ea and similar apply again.

Mr-Pine and others added 2 commits August 7, 2026 15:52
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dot-asm

dot-asm commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

You don't actually have to answer, but I wonder what gets broken.

Comment thread scripts/to_zdsl.py Outdated
Comment thread scripts/to_zdsl.py Outdated
@Mr-Pine

Mr-Pine commented Aug 10, 2026

Copy link
Copy Markdown
Author

You don't actually have to answer, but I wonder what gets broken.

No address variable that contains a register or cfa matches on $1ea and similar anymore. For example, to_zdsl.py ran on the code in #25 results in

(* main: *)
main:;
(* #! -> SP = 0x7fffffffd298 *)
#! 0x7fffffffd298 = 0x7fffffffd298;
(* sub    $0x8,%rsp *)
;
(* movq   $0x0,(%rsp)                              #! EA = Lcfa_0x008; Segment = [stack] *)
movq   $0x0,%%Lcfa_0x008                              #! Lcfa_0x008 = Lcfa_0x008; [stack] = [stack];
(* vpbroadcastq (%rsp),%ymm0                       #! EA = Lcfa_0x008; Segment = [stack]; Value = 0x0000000000000000 0x00007ffff7c2a1ca 0x00007fffffffd2e0 0x00007fffffffd3b8 *)
vpbroadcastq %%Lcfa_0x008,%%ymm0                       #! Lcfa_0x008 = Lcfa_0x008; [stack] = [stack]; 0x0000000000000000 0x00007ffff7c2a1ca 0x00007fffffffd2e0 0x00007fffffffd3b8 = 0x0000000000000000 0x00007ffff7c2a1ca 0x00007fffffffd2e0 0x00007fffffffd3b8;
(* movq   $0x42,(%rsp)                             #! EA = Lcfa_0x008; Segment = [stack] *)
movq   $0x42,%%Lcfa_0x008                             #! Lcfa_0x008 = Lcfa_0x008; [stack] = [stack];
(* movddup (%rsp),%xmm0                       #! EA = Lcfa_0x008; Segment = [stack]; Value = 0x0000000000000042 0x00007ffff7c2a1ca *)
movddup %%Lcfa_0x008,%%xmm0                       #! Lcfa_0x008 = Lcfa_0x008; [stack] = [stack]; 0x0000000000000042 0x00007ffff7c2a1ca = 0x0000000000000042 0x00007ffff7c2a1ca;
(* sub    $0x20,%rsp *)
;
(* vmovdqa %ymm0,(%rsp)                            #! EA = Lcfa_0x028; Segment = [stack] *)
vmovdqa %%ymm0,%%Lcfa_0x028                            #! Lcfa_0x028 = Lcfa_0x028; [stack] = [stack];
(* mov    (%rsp),%rax                              #! EA = Lcfa_0x028; Segment = [stack]; Value = 0x0000000000000042 *)
mov rax Lcfa_0x028;
(* add    $0x28,%rsp *)
;
(* #! <- SP = 0x7fffffffd298 *)
#! 0x7fffffffd298 = 0x7fffffffd298;
(* #ret *)
#ret;

instead of

(* main: *)
main:;
(* #! -> SP = 0x7fffffffd298 *)
#! 0x7fffffffd298 = 0x7fffffffd298;
(* sub    $0x8,%rsp *)
;
(* movq   $0x0,(%rsp)                              #! EA = Lcfa_0x008; Segment = [stack] *)
mov Lcfa_0x008 0x0;
(* vpbroadcastq (%rsp),%ymm0                       #! EA = Lcfa_0x008; Segment = [stack]; Value = 0x0000000000000000 0x00007ffff7c2a1ca 0x00007fffffffd2e0 0x00007fffffffd3b8 *)
broadcast %ymm0@sint64[4] 4 [Lcfa_0x008];
(* movq   $0x42,(%rsp)                             #! EA = Lcfa_0x008; Segment = [stack] *)
mov Lcfa_0x008 0x42;
(* movddup (%rsp),%xmm0                       #! EA = Lcfa_0x008; Segment = [stack]; Value = 0x0000000000000042 0x00007ffff7c2a1ca *)
mov %xmm0@uint64[2] [ Lcfa_0x008, Lcfa_0x008 ];
(* sub    $0x20,%rsp *)
;
(* vmovdqa %ymm0,(%rsp)                            #! EA = Lcfa_0x028; Segment = [stack] *)
mov [Lcfa_0x028,Lcfa_0x028[+8],Lcfa_0x028[+16],Lcfa_0x028[+24]] %ymm0@uint64[4];
(* mov    (%rsp),%rax                              #! EA = Lcfa_0x028; Segment = [stack]; Value = 0x0000000000000042 *)
mov rax Lcfa_0x028;
(* add    $0x28,%rsp *)
;
(* #! <- SP = 0x7fffffffd298 *)
#! 0x7fffffffd298 = 0x7fffffffd298;
(* #ret *)
#ret;

Comment thread scripts/to_zdsl.py Outdated
@dot-asm

dot-asm commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Things don't seem to add up. Consider

vmovdqu %ymm0,(%rsp)

Originally it was translated to

mov [L0x1234000, L0x1234008, L0x1234010, L0x1234018] %ymm0@uint64[4];

What would be the expectation for Lcfa_0x028? I get

mov [Lcfa_0x028, Lcfa_0x28[+8], ...

Is it right? What doesn't add up is that I don't see square brackets in compute_address that is being modified here...

@Mr-Pine

Mr-Pine commented Aug 10, 2026

Copy link
Copy Markdown
Author

Oh right, I did not catch that, sorry. That came from the still-old address_offset_pattern regex, leading to it never actually being resolved by compute_address.

I now get

mov [Lcfa_0x028,Lcfa_0x020,Lcfa_0x018,Lcfa_0x010] %ymm0@uint64[4];

which looks correct to me.

Comment thread scripts/cryptoline.py
base = int(base, 0)
addr = base + offset
addr = ("L0x%0." + str(l) + "x") % addr
disp = match.group(2)

@dot-asm dot-asm Aug 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In cases where addresses fall "too far" from the input arguments or CFA, itrace.py will fall back to the original format of L0x1234000. This needs to be handled. Additionally, there is an implicit ambiguity in the function declaration. I mean the ea_pattern=default_ea_pattern part, which doesn't require that the pattern yields two match groups. In other words one needs to be able to handle variable amount of matche groups. Alternatively I wonder if it's possible to solve it with r'L(?:[a-z]\w+_)?(0x\w+)', i.e. with a single-group pattern, and use match.start(1) to split the input to prefix, L, Lcfa_, etc., and the number...

@Mr-Pine Mr-Pine Aug 10, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think explicitly failing if the if an offset crosses the current stack frame is the best we can do. This should never occur in actually traced code and I don't see a good way to recover the stack base address. Did not read your comment correctly
The original format is already handled by the prefix = ... if base else "L" line.

The ambiguity on what ea_pattern should be was there before as well: It expected at least one group.
I honestly think the best option is to remove the argument entirely and always use default_ea_pattern. But I could also add a comment documenting what kind of match ea_pattern is expected to produce.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original format is already handled by the prefix = ... if base else "L" line.

Right! Sorry about the distraction then. I suppose it could have been more readable... I mean it wasn't clear to me... But on the other hand I'm not in position to claim a connoisseurship here :-) :-) :-)

The ambiguity on what ea_pattern should be was there before as well: It expected at least one group.

My rationale is that it's not reasonable to expect more than one match group, because reference to match.group(>1) is prone to triggerring an exception. Unless of course one handles variable amount of groups explicitly. But it's perfectly reasonable to expect at least one group in if match:...

I honestly think the best option is to remove the argument entirely and always use default_ea_pattern. But I could also add a comment documenting what kind of match ea_pattern is expected to produce.

As for omitting the default_ea_pattern. I would agree, but I'd leave it to the actual maintainers to weigh in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants