Skip to content
ida-normalizer.sh 8.8 KiB
Newer Older
#!/bin/bash

if [ $# -eq 0 ]; then
  echo "No arguments supplied"
  exit 1
fi

filename=$1
logname=$2

# Ad hoc fix for base32 while
sed -i -e 's/FUN_00402750(puParm2, puParm3, local_50)/FUN_00402750(puParm2, puParm3, local_50, local_50)/g' $filename

# Declare undeclared variables
>declarations.tmp
>declarations.txt
>unique-declarations.txt
grep "error: use of undeclared identifier" $logname | sed -n -e "s/^.*identifier '\([^;]*\)'.*$/\1/p" &> declarations.txt

for variable in `cat declarations.txt`
do
  echo "long $variable;" >> declarations.tmp
done

# The declaration is postponed at the end of the processing, to avoid changing line numbers in the middle of the work.
cat declarations.tmp | sort | uniq > unique-declarations.txt

# Remove temporary files.
rm declarations.txt declarations.tmp

# Fix erroneous function declarations
> mismatching-functions.txt
grep "error: too many arguments to function call" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> many-arguments.txt
grep "error: too few arguments to function call" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> few-arguments.txt

cat few-arguments.txt many-arguments.txt | sort | uniq > mismatching-functions.txt
rm few-arguments.txt many-arguments.txt

# Fix erroneous function calls (indirect jumps in ghidra)
> void-pointer.txt
> long-pointer.txt
grep "error: called object type 'void' is not a function or function pointer" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> void-pointer.txt
grep "error: called object type 'long' is not a function or function pointer" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> long-pointer.txt
cat void-pointer.txt long-pointer.txt > function-pointer.txt
rm void-pointer.txt long-pointer.txt

# Fix incomatible types assignements
> incompatible-type.txt
grep "from incompatible type 'void'" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> incompatible-type.txt

# Remove void parameter from functions

sed -i -e "s/(void)/()/g" $filename

# Remove variables with names containing a .
>variables-with-point.txt
grep "member reference base type" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> variables-with-point.txt

for line in `cat variables-with-point.txt`
do
  sed -i -e "${line}s/\.//" $filename
done
rm variables-with-point.txt

# Remove "where arithmetic or pointer" errors
grep "^.* where arithmetic or pointer type is required" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> operand-types.txt
grep "error: array type .* is not assignable" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> array-type.txt
grep "error: indirection requires pointer operand" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> indirection.txt
grep "error: invalid operands to binary expression" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> operands.txt
grep "error: operand of type 'double' cannot be cast to a pointer type" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> operands-double.txt
grep "error: pointer cannot be cast to type 'double'" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> operands-pointer-double.txt
grep "error: subscripted value is not an array, pointer, or vector" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> subscripted-array.txt
grep "error: void function" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> return-value.txt
grep "error: hex escape sequence out of range" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> hex-escape.txt
grep "error: expression is not assignable" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> expr-not-assignable.txt
grep "error: assigning to 'union __m128i' from incompatible type 'long long'" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> assign-union.txt
grep "error: 'uint8 \*' (aka 'unsigned char \*') and 'char \*' are not pointers to compatible types" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> pointer-compatible.txt
grep "error: 'char \*' and 'uint8 \*' (aka 'unsigned char \*') are not pointers to compatible types" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt
grep "error: initializer element is not a compile-time constant" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt
grep "error: assigning to 'union __m128i' from incompatible type 'int'" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt
grep "error: cast to union type from type 'long long' not present in union" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt
grep "error: cannot take the address of an rvalue of type 'int'" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt
grep "error: integer literal is too large to be represented in any integer type" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt
grep "error: cast to union type from type 'int' not present in union" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt
grep "error: must use 'union' tag to refer to type '__m128'" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt
grep "error: assigning to 'union __m128' from incompatible type 'int'" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt
grep "error: cast to union type from type 'long' not present in union" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt
grep "error: cast to union type from type '__int128' not present in union" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt
grep "error: cast to union type from type 'union __m128i' not present in union" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt
grep "error: cast to union type from type 'union __m128' not present in union" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &>> pointer-compatible.txt

# Collect all the lines containing solvable errors in an unique index file (just to improve performance).
cat operand-types.txt array-type.txt indirection.txt operands.txt operands-double.txt operands-pointer-double.txt subscripted-array.txt return-value.txt incompatible-type.txt function-pointer.txt mismatching-functions.txt hex-escape.txt expr-not-assignable.txt assign-union.txt pointer-compatible.txt > final-to-comment.txt
rm operand-types.txt array-type.txt indirection.txt operands.txt operands-double.txt operands-pointer-double.txt subscripted-array.txt return-value.txt incompatible-type.txt function-pointer.txt mismatching-functions.txt hex-escape.txt expr-not-assignable.txt assign-union.txt pointer-compatible.txt

cat final-to-comment.txt | sort | uniq > unique-final-to-comment.txt
rm final-to-comment.txt

for line in `cat unique-final-to-comment.txt`
do
  broken_line=`sed -n ${line}p $filename`
  echo "$broken_line"
  if echo "$broken_line" | grep "if (.*{"
  then
    sed -i -e "${line}s/if (.*{/if (1) {/" $filename
  elif echo "$broken_line" | grep "while (.*{"
  then
    sed -i -e "${line}s/while (.*{/while (1) {/" $filename
  elif echo "$broken_line" | grep "if (.*)"
  then
    sed -i -e "${line}s/if (.*)/if (1)/" $filename
  elif echo "$broken_line" | grep "} while (.*);"
  then
    sed -i -e "${line}s/} while (.*);/} while (1);/" $filename
  elif echo "$broken_line" | grep "switch (.*) {"
  then
    sed -i -e "${line}s/switch (.*) {/switch (1) {/" $filename
  else
    sed -i -e "${line}s/^/ imperfetction_wrapper();\/\//" $filename
  fi
done
rm unique-final-to-comment.txt

# Correct erroneous pointer casts
grep "error: pointer cannot be cast to type 'double'" $logname | sed -n -e "s/^.*\.c:\([0-9]*\):.*$/\1/p" &> pointer-casts.txt
for line in `cat pointer-casts.txt`
do
  sed -i -e "${line}s/(double)pplVar15/1/" $filename
  sed -i -e "${line}s/(double)pplVar16/1/" $filename
  sed -i -e "${line}s/(long \*\*)local_a58/local_a58/" $filename
done
rm pointer-casts.txt

# Ad hoc fix for no statement after a goto label
sed -i -e "s/^.*LAB_004020c6:/LAB_004020c6:\nlVar13 = lVar13;/g" $filename
sed -i -e "s/^.*LAB_00409d1c:/LAB_00409d1c:\npuVar14 = puVar14;/g" $filename
sed -i -e "s/^.*LAB_0040af5c:/LAB_0040af5c:\npuVar14 = puVar14;/g" $filename
sed -i -e "s/^.*LAB_0040b47c:/LAB_0040b47c:\npuVar14 = puVar14;/g" $filename
sed -i -e "s/^.*LAB_004029b2:/LAB_004029b2:\nbVar1 = bVar1;/g" $filename
sed -i -e "s/^.*LAB_0040668c:/LAB_0040668c:\lVar8 =lVar8;/g" $filename
sed -i -e "s/^.*LAB_00401a7b:/LAB_00401a7b:\npuVar14 = puVar14;/g" $filename
sed -i -e "s/^.*LAB_00404656:/LAB_00404656:\nuVar8 = uVar8;/g" $filename

sed -i -e "s/^.*LAB_00404656:/LAB_00404656:\nuVar8 = uVar8;/g" $filename
sed -i -e "s/^.*LAB_00404656:/LAB_00404656:\nuVar8 = uVar8;/g" $filename
sed -i -e "s/^.*LAB_00404656:/LAB_00404656:\nuVar8 = uVar8;/g" $filename

# Add the missing variable declarations (we need to do it as last thing, to
# to avoid changing the lines number for the other operations)
sed -i -e "10r unique-declarations.txt" $filename
rm unique-declarations.txt