Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why i using CallingConvention get invalid prototype #4559

Open
gaaabaa opened this issue Apr 2, 2024 · 4 comments
Open

Why i using CallingConvention get invalid prototype #4559

gaaabaa opened this issue Apr 2, 2024 · 4 comments
Labels
question Issues that do not require code changes

Comments

@gaaabaa
Copy link

gaaabaa commented Apr 2, 2024

Question

Hi angr team! Excuse my English. I just recently started working with angr. And ran into a problem when researching functions in fauxware. Using CallingConvention for authenticate function I get prototype (long long (64 bits), long long (64 bits)) -> int (32 bits) although the prototype should be (char*,char*) -> int. How can I fix this and why it happens like this . Can you explain and if possible give me a code sample. I using code

 import angr
 p = angr.Project("fauxware",auto_load_libs = False)
 cfg = p.analyses.CFGFast(normalize=True,cross_references=True)
 func = cfg.kb.functions[addr]
 p.analyses.CompleteCallingConventions(cfg= cfg,recover_variables=True)
 a = p.analyses.VariableRecoveryFast(func=func,func_args=conv.prototype)
 conv = p.analyses.CallingConvention(analyze_callsites=True,cfg=cfg,func=cfg.kb.functions[func_addr])
 print(conv.prototype)
@gaaabaa gaaabaa added needs-triage Issue has yet to be looked at by a maintainer question Issues that do not require code changes labels Apr 2, 2024
@ltfish ltfish removed the needs-triage Issue has yet to be looked at by a maintainer label Apr 2, 2024
@ltfish
Copy link
Member

ltfish commented Apr 2, 2024

The default calling convention analysis does not recover variable or function argument types. You'll want to decompile the function and see if the decompiler can give you a function prototype with more precise argument types. Try doing this at the end of your script:

dec = p.analyses.Decompiler(func, cfg=cfg.model)
print(func.prototype)

@gaaabaa
Copy link
Author

gaaabaa commented Apr 3, 2024

thanks it works. but I decided to try on another example where I analyzed the function func and instead of getting the prototype (int,int) I got (unsigned long,unsigned long). Also I was wondering what prototypes angr will output when embedding sanitizer in an executable file using 'gcc -fsanitize=undefined test.c -o test' and the prototype I got was (unsigned long,unsigned long,unsigned long,unsigned long,unsigned long,unsigned long,unsigned long) how it happened. Source text of the file I tried to analyze

 int func(int a,int b)
{
    int c = a / b;
    printf("%d",c);
    return c;
}
int main()
{
    int a,b,c;
    scanf("%d",&a);
    scanf("%d",&b);
    if(a * b >= 0)
    {
        if( a < 12411)
        {
            if(b > 5312)
            {
                if ( b > a)
                {
                    c = func(a,b);
                    printf("vurn");
                }
                else
                {
                    c = a * b;
                    printf("%d",c);
                }
            }
            else
            {
                printf(" b > 5312 ");
            }
        }
        else
        {
            c = a + b;
            printf("%d",c);
        }
        
        printf("1 branch");
    }
    else
    {
        if(a < 0)
        {
            printf("a < 0");
        }
    }
    return 0;
}

@ltfish
Copy link
Member

ltfish commented Apr 3, 2024

instead of getting the prototype (int,int) I got (unsigned long,unsigned long)

angr decompiler does not aggressively narrow register-passing arguments (e.g., long long ->int) during decompilation, so this can totally be the expected behavior. But I can't be sure unless you post your binary.

Also I was wondering what prototypes angr will output when embedding sanitizer in an executable file using 'gcc -fsanitize=undefined test.c -o test'

As of now, angr decompiler is not aware of sanitizers and will not try to eliminate sanitizer artifacts. I can imagine the sanitization logic will attempt to load all possible register-passing arguments at the beginning of your function, which will lead angr decompiler to treat all loaded registers as argument-passing containers. The end result is a function prototype that is different from the one in source. However, this is the expected behavior (unless angr decompiler is aware of sanitizers one day).

@gaaabaa
Copy link
Author

gaaabaa commented Apr 6, 2024

thanks ,there source and error ERROR | 2024-04-05 00:40:57,076 | angr.analyses.decompiler.structured_codegen.c | Store data lifted to a C type with a different size. Decompilation output will be wrong
test.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Issues that do not require code changes
Projects
None yet
Development

No branches or pull requests

2 participants