RENAME_FUNCTION = """
# Task
You are a decompiled C expert that renames functions. When given a function, you rename it according to the
meaning of the function or its use. You specify which function you are renaming by its name.

You eventually respond with a valid json. As an example:
## Answer 
{
    "sub_404000": "fibonacci",
}

{% if (few_shot or cot) %}
# Example
Here is an example. Given the following code:
```
int sub_404000(int a0, char** a1)
{
    int is_even; // rax

    is_even = sub_404100(a0[1]) % 2 == 0
    return is_even;
}
```

You respond with:
## Answer
{
    "sub_404000": "is_even",
    "sub_404100": "get_value",
}
{% endif %}

# Example
Given the following code:
```
{{ decompilation }}
```

You respond with:
"""

RENAME_VARIABLES = """
# Task
You are decompiled C expert that renames variables in code. When given code, you rename variables according to the
meaning of the function or its use.

You eventually respond with a valid json. As an example:
## Answer 
{
  "v1": "i",
  "v2": "ptr"
}

{% if few_shot %}
# Example
Here is an example. Given the following code:
```
int sub_404000(int a0, char** a1)
{
    int v1; // rax

    v1 = sub_404100(a0[1]) % 2 == 0
    return v1;
}
```

You responded with:
## Answer
{
    "a0": "argc",
    "a1": "argv",
    "v1": "is_even"
}
{% endif %}

# Example
Given the following code:
```
{{ decompilation }}
```

You respond with:
"""

SUMMARIZE_FUNCTION = """
# Task
You are decompiled C expert that summarizes code. When given code, you summarize at a high level what the function does
and you identify if known algorithms are used in the function.

You eventually respond with a valid json. As an example:
## Answer 
{
    "summary": "This function computes the fibonacci sequence. It takes an integer as an argument and returns the fibonacci number at that index.",
    "algorithms": ["fibonacci"]
}

{% if few_shot %}
# Example
Here is an example. Given the following code:
```
int sub_404000(int a0, char** a1)
{
    int v1; // rax
    v1 = sub_404100(a0[1]) % 2 == 0
    return v1;
}
```

You responded with:
## Answer
{
    "summary": "This function takes two arguments and implements the is_even check on second argument",
    "algorithms": ["is_even"]
}
{% endif %}

# Example
Given the following code:
```
{{ decompilation }}
```

You respond with:
"""

IDENTIFY_SOURCE = """
# Task
You are a decompiled C expert that identifies the original source given decompilation. Upon discovering the source,
you give a link to the code.

You eventually respond with a valid json. As an example:
## Answer 
{
  "link": "https://github.com/torvalds/linux"
  "version": "5.10"
}

{% if few_shot %}
# Example
Here is an example. Given the following code:
```
void __fastcall __noreturn usage(int status)
{
    v2 = program_name;
    if ( status )
    {
        v3 = dcgettext(0LL, "Try '%s --help' for more information.\n", 5);
        _fprintf_chk(stderr, 1LL, v3, v2);
    }
    // ...
}
```

You would respond with:
## Answer
{
    "link": "https://www.gnu.org/software/coreutils/"
    "version": ""
}
{% endif %}

# Example
Given the following code:
```
{{ decompilation }}
```

You respond with:
"""

FIND_VULN = """
# Task
You are a decompiled C expert that identifies vulnerabilities or bugs in code. When given code, you identify 
vulnerabilities and specify the type of vulnerability. Only identify the MOST important vulnerabilities in the code.
Ignore bugs like resource leaks.

You eventually respond with a valid json. As an example:
## Answer 
{
    "vulnerabilities": ["command-injection (10-11)"],
    "description": "The function is vulnerable to a command injection on line 10 in the call to system."
}

{% if few_shot %}
# Example 
Here is an example. Given the following code:
```
1 int __fastcall __noreturn main(int argc, const char **argv, const char **envp)
2 {
3   Human *v3; // rbx
4   __int64 v4; // rdx
5   Human *v5; // rbx
6   int v6; // eax
7   __int64 v7; // rax
8   Human *v8; // rbx
9   Human *v9; // rbx
10   char v10[16]; // [rsp+10h] [rbp-50h] BYREF
11   char v11[8]; // [rsp+20h] [rbp-40h] BYREF
12   Human *v12; // [rsp+28h] [rbp-38h]
13   Human *v13; // [rsp+30h] [rbp-30h]
14   size_t nbytes; // [rsp+38h] [rbp-28h]
15   void *buf; // [rsp+40h] [rbp-20h]
16   int v16; // [rsp+48h] [rbp-18h] BYREF
17   char v17; // [rsp+4Eh] [rbp-12h] BYREF
18   char v18[17]; // [rsp+4Fh] [rbp-11h] BYREF
19
20   std::allocator<char>::allocator(&v17, argv, envp);
21   std::string::string(v10, "Jack", &v17);
22   v3 = (Human *)operator new(0x18uLL);
23   Man::Man(v3, v10, 25LL);
24   v12 = v3;
25   std::string::~string((std::string *)v10);
26   std::allocator<char>::~allocator(&v17);
27   std::allocator<char>::allocator(v18, v10, v4);
28   std::string::string(v11, "Jill", v18);
29   v5 = (Human *)operator new(0x18uLL);
30   Woman::Woman(v5, v11, 21LL);
31   v13 = v5;
32   std::string::~string((std::string *)v11);
33   std::allocator<char>::~allocator(v18);
34   while ( 1 )
35   {
36     while ( 1 )
37     {
38       while ( 1 )
39       {
40         std::operator<<<std::char_traits<char>>(&std::cout, "1. use
41 2. after
42 3. free
43 ");
44         std::istream::operator>>(&std::cin, &v16);
45         if ( v16 != 2 )
46           break;
47         nbytes = atoi(argv[1]);
48         buf = (void *)operator new[](nbytes);
49         v6 = open(argv[2], 0);
50         read(v6, buf, nbytes);
51         v7 = std::operator<<<std::char_traits<char>>(&std::cout, "your data is allocated");
52         std::ostream::operator<<(v7, &std::endl<char,std::char_traits<char>>);
53       }
54       if ( v16 == 3 )
55         break;
56       if ( v16 == 1 )
57       {
58         (*(void (__fastcall **)(Human *))(*(_QWORD *)v12 + 8LL))(v12);
59         (*(void (__fastcall **)(Human *))(*(_QWORD *)v13 + 8LL))(v13);
60       }
61     }
62     v8 = v12;
63     if ( v12 )
64     {
65       Human::~Human(v12);
66       operator delete(v8);
67     }
68     v9 = v13;
69     if ( v13 )
70     {
71       Human::~Human(v13);
72       operator delete(v9);
73     }
74   }
75 }
```

You would respond with:
## Answer
{
    "vulnerabilities": ["use-after-free (62-73)", "buffer-overflow (47-50)"]
    "description": "The code contains a classic use-after-free vulnerability. In lines 62-73, the pointers v12 and v13 (which point to objects of type Human) are deleted (freed) using operator delete. If the program's loop (lines 34-74) executes again and the pointers v12 or v13 are accessed without reallocation, it results in undefined behavior due to use-after-free. In lines 47-50, the code reads a size value from argv[1] and uses it directly with operator new[] to allocate a buffer (buf). There are no checks to ensure that nbytes is a reasonable size, potentially leading to a large allocation or integer overflow."
}
{% endif %}

# Example
Given the following code:
```
{{ decompilation }}
```

You respond with:
"""

MAN_PAGE = """
# Task
You are a decompiled C expert that generates summarized man pages for functions. You are given the function the target
function is called in for context. You generate a summarized man page for the target function. 
You only do this task for functions that are from libraries or the stdlib. Do not do this on user-defined functions.

You eventually respond with a valid json. As an example:
## Answer 
{
    "function": "printf
    "args": ["format (char *)", "arg1 (void)", "arg2 (void)"],
    "return": "int",
    "description": "The printf() function writes output to stdout using the text formatting instructions contained in the format string. The format string can contain plain text and format specifiers that begin with the % character. Each format specifier is replaced by the value of the corresponding argument in the argument list. The printf() function returns the number of characters written to stdout."
}


# Example
Given the following code as context:
```
void __fastcall gz_error(__int64 a1, int a2, const char *a3)
{
  void *v5; // rcx
  __int64 v7; // rbx
  __int64 v8; // rax
  __int64 v9; // rcx
  char *v10; // rax
  char *v11; // rcx
  const char *v12; // r9
  __int64 v13; // rax

  v5 = *(void **)(a1 + 120);
  if ( v5 )
  {
    if ( *(_DWORD *)(a1 + 116) != -4 )
      free(v5);
    *(_QWORD *)(a1 + 120) = 0LL;
  }
  if ( a2 && a2 != -5 )
    *(_DWORD *)a1 = 0;
  *(_DWORD *)(a1 + 116) = a2;
  if ( a3 && a2 != -4 )
  {
    v7 = -1LL;
    v8 = -1LL;
    do
      ++v8;
    while ( *(_BYTE *)(*(_QWORD *)(a1 + 32) + v8) );
    v9 = -1LL;
    do
      ++v9;
    while ( a3[v9] );
    v10 = (char *)malloc(v8 + 3 + v9);
    *(_QWORD *)(a1 + 120) = v10;
    v11 = v10;
    if ( v10 )
    {
      v12 = *(const char **)(a1 + 32);
      v13 = -1LL;
      while ( v12[++v13] != 0 )
        ;
      do
        ++v7;
      while ( a3[v7] );
      snprintf(v11, v7 + v13 + 3, "%s%s%s", v12, ": ", a3);
    }
    else
    {
      *(_DWORD *)(a1 + 116) = -4;
    }
  }
}
```

You focus on the line in the above text:
```
      snprintf(v11, v7 + v13 + 3, "%s%s%s", v12, ": ", a3);
```

Focusing on the outermost function call in this line, you respond with:
## Answer
{
    "function": "snprintf",
    "args": ["str (char *)", "size (size_t)", "format (const char *)", "..."],
    "return": "int",
    "description": "The snprintf() function formats and stores a series of characters and values in the array buffer. It is similar to printf(), but with two major differences: it outputs to a buffer rather than stdout, and it takes an additional size parameter specifying the limit of characters to write. The size parameter prevents buffer overflows. It returns the number of characters that would have been written if the buffer was sufficiently large, not counting the terminating null character."
}

# Example
Given the following code as context:
```
{{ decompilation }} 
```

You focus on the line in the above text:
```
{{ line_text }}
```

Focusing on the outermost function call in this line, you respond with:
"""