HyperDbg Debugger
Loading...
Searching...
No Matches
script-engine.c File Reference

Script engine parser and codegen. More...

#include "pch.h"

Functions

UINT64 ScriptEngineConvertNameToAddress (const char *FunctionOrVariableName, PBOOLEAN WasFound)
 Converts name to address.
 
UINT32 ScriptEngineLoadFileSymbol (UINT64 BaseAddress, const char *PdbFileName, const char *CustomModuleName)
 
VOID ScriptEngineSetTextMessageCallback (PVOID Handler)
 Set the message handler as an alternative to printf.
 
UINT32 ScriptEngineUnloadAllSymbols ()
 Unload all the previously loaded symbols.
 
UINT32 ScriptEngineUnloadModuleSymbol (char *ModuleName)
 Unload a special pdb.
 
UINT32 ScriptEngineSearchSymbolForMask (const char *SearchMask)
 Search for a special mask.
 
BOOLEAN ScriptEngineGetFieldOffset (CHAR *TypeName, CHAR *FieldName, UINT32 *FieldOffset)
 Get offset of a field from the structure.
 
BOOLEAN ScriptEngineGetDataTypeSize (CHAR *TypeName, UINT64 *TypeSize)
 Get size of a data type (structure)
 
BOOLEAN ScriptEngineCreateSymbolTableForDisassembler (void *CallbackFunction)
 Create symbol table for disassembler.
 
BOOLEAN ScriptEngineConvertFileToPdbPath (const char *LocalFilePath, char *ResultPath)
 Convert local file to pdb path.
 
BOOLEAN ScriptEngineSymbolInitLoad (PVOID BufferToStoreDetails, UINT32 StoredLength, BOOLEAN DownloadIfAvailable, const char *SymbolPath, BOOLEAN IsSilentLoad)
 Initial load of the symbols.
 
BOOLEAN ScriptEngineShowDataBasedOnSymbolTypes (const char *TypeName, UINT64 Address, BOOLEAN IsStruct, PVOID BufferAddress, const char *AdditionalParameters)
 Show data based on symbol types.
 
VOID ScriptEngineSymbolAbortLoading ()
 Cancel loading.
 
BOOLEAN ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails (const char *LocalFilePath, char *PdbFilePath, char *GuidAndAgeDetails, BOOLEAN Is32BitModule)
 Convert file to pdb attributes for symbols.
 
PVOID ScriptEngineParse (char *str)
 The entry point of script engine.
 
void CodeGen (PTOKEN_LIST MatchedStack, PUSER_DEFINED_FUNCTION_NODE *UserDefinedFunctionHead, PSYMBOL_BUFFER CodeBuffer, PTOKEN Operator, PSCRIPT_ENGINE_ERROR_TYPE Error)
 Script Engine code generator.
 
UINT64 BooleanExpressionExtractEnd (char *str, BOOL *WaitForWaitStatementBooleanExpression, PTOKEN CurrentIn)
 Computes the boolean expression length starting from the current input position.
 
void ScriptEngineBooleanExpresssionParse (UINT64 BooleanExpressionSize, PTOKEN FirstToken, PTOKEN_LIST MatchedStack, PUSER_DEFINED_FUNCTION_NODE *UserDefinedFunctionHead, PSYMBOL_BUFFER CodeBuffer, char *str, char *c, PSCRIPT_ENGINE_ERROR_TYPE Error)
 LALR parser used for parsing boolean expression.
 
PSYMBOL NewSymbol (void)
 Allocates a new SYMBOL and returns the reference to it.
 
PSYMBOL NewStringSymbol (PTOKEN Token)
 Allocates a new SYMBOL with string type and returns the reference to it.
 
PSYMBOL NewWstringSymbol (PTOKEN Token)
 Allocates a new SYMBOL with wstring type and returns the reference to it.
 
unsigned int GetSymbolHeapSize (PSYMBOL Symbol)
 Returns the number of SYMBOL objects (24 bytes) allocated by string or wstring sybmol.
 
void RemoveSymbol (PSYMBOL *Symbol)
 Frees the memory allocate by this Symbol.
 
void PrintSymbol (PVOID Symbol)
 Prints symbol.
 
PSYMBOL ToSymbol (PTOKEN Token, PSCRIPT_ENGINE_ERROR_TYPE Error)
 Converts Token to Symbol and returns the reference to it.
 
PSYMBOL_BUFFER NewSymbolBuffer (void)
 allocates a new Symbol Buffer and returns the reference to it
 
void RemoveSymbolBuffer (PVOID SymbolBuffer)
 Frees the memory allocated by SymbolBuffer.
 
PSYMBOL_BUFFER PushSymbol (PSYMBOL_BUFFER SymbolBuffer, const PSYMBOL Symbol)
 Gets a symbol and push it into the symbol buffer.
 
void PrintSymbolBuffer (const PVOID SymbolBuffer)
 Prints a symbol buffer.
 
unsigned long long int RegisterToInt (char *str)
 Converts register string to integer.
 
unsigned long long int PseudoRegToInt (char *str)
 Converts pseudo register string to integer.
 
unsigned long long int SemanticRuleToInt (char *str)
 Converts a sematinc rule token to integer.
 
char * HandleError (PSCRIPT_ENGINE_ERROR_TYPE Error, char *str)
 Prints some information about the error.
 
int GetGlobalIdentifierVal (PTOKEN Token)
 Returns the integer assigned to global variable.
 
int GetLocalIdentifierVal (PTOKEN Token)
 Returns the integer assigned to local variable.
 
int NewGlobalIdentifier (PTOKEN Token)
 Allocates a new global variable and returns the integer assigned to it.
 
int NewLocalIdentifier (PTOKEN Token)
 Allocates a new local variable and returns the integer assigned to it.
 
int NewFunctionParameterIdentifier (PTOKEN Token)
 
int GetFunctionParameterIdentifier (PTOKEN Token)
 
int LalrGetRhsSize (int RuleId)
 Returns the size of Right Hand Side (RHS) of a rule.
 
BOOL LalrIsOperandType (PTOKEN Token)
 Returns TRUE if the Token can be the operand of an operator.
 
BOOLEAN ScriptEngineSetHwdbgInstanceInfo (HWDBG_INSTANCE_INFORMATION *InstancInfo)
 Set hwdbg instance info for the script engine.
 
BOOLEAN FuncGetNumberOfOperands (UINT64 FuncType, UINT32 *NumberOfGetOperands, UINT32 *NumberOfSetOperands)
 Script Engine get number of operands.
 

Variables

HWDBG_INSTANCE_INFORMATION g_HwdbgInstanceInfo
 Instance information of the current hwdbg debuggee.
 
BOOLEAN g_HwdbgInstanceInfoIsValid
 Shows whether the instance info is valid (received) or not.
 

Detailed Description

Script engine parser and codegen.

Author
M.H. Gholamrezaei (mh@hy.nosp@m.perd.nosp@m.bg.or.nosp@m.g)
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2020-10-22

Function Documentation

◆ BooleanExpressionExtractEnd()

UINT64 BooleanExpressionExtractEnd ( char * str,
BOOL * WaitForWaitStatementBooleanExpression,
PTOKEN CurrentIn )

Computes the boolean expression length starting from the current input position.

Parameters
str
WaitForWaitStatementBooleanExpression
CurrentIn
Returns
UINT64
2233{
2234 UINT64 BooleanExpressionSize = 0;
2235 if (*WaitForWaitStatementBooleanExpression)
2236 {
2237 while (str[InputIdx + BooleanExpressionSize - 1] != ';')
2238 {
2239 BooleanExpressionSize += 1;
2240 }
2241 *WaitForWaitStatementBooleanExpression = FALSE;
2242 return InputIdx + BooleanExpressionSize - 1;
2243 }
2244 else
2245 {
2246 int OpenParanthesesCount = 1;
2247 if (!strcmp(CurrentIn->Value, "("))
2248 {
2249 OpenParanthesesCount++;
2250 }
2251 while (str[InputIdx + BooleanExpressionSize - 1] != '\0')
2252 {
2253 if (str[InputIdx + BooleanExpressionSize - 1] == ')')
2254 {
2255 OpenParanthesesCount--;
2256 if (OpenParanthesesCount == 0)
2257 {
2258 return InputIdx + BooleanExpressionSize - 1;
2259 }
2260 }
2261 else if (str[InputIdx + BooleanExpressionSize - 1] == '(')
2262 {
2263 OpenParanthesesCount++;
2264 }
2265 BooleanExpressionSize++;
2266 }
2267 }
2268 return -1;
2269}
#define FALSE
Definition BasicTypes.h:54
unsigned __int64 UINT64
Definition BasicTypes.h:21
unsigned int InputIdx
number of read characters from input
Definition scanner.h:30
char * Value
Definition common.h:74

◆ CodeGen()

void CodeGen ( PTOKEN_LIST MatchedStack,
PUSER_DEFINED_FUNCTION_NODE * UserDefinedFunctionHead,
PSYMBOL_BUFFER CodeBuffer,
PTOKEN Operator,
PSCRIPT_ENGINE_ERROR_TYPE Error )

Script Engine code generator.

Parameters
MatchedStack
CodeBuffer
Operator
Error
527{
528 PTOKEN Op0 = NULL;
529 PTOKEN Op1 = NULL;
530 PTOKEN Op2 = NULL;
531 PTOKEN Temp = NULL;
532
533 PSYMBOL OperatorSymbol = NULL;
534 PSYMBOL Op0Symbol = NULL;
535 PSYMBOL Op1Symbol = NULL;
536 PSYMBOL Op2Symbol = NULL;
537 PSYMBOL TempSymbol = NULL;
538 VARIABLE_TYPE * VariableType = NULL;
539
540 //
541 // It is in user-defined function if CurrentFunctionSymbol is not null
542 //
543 static PUSER_DEFINED_FUNCTION_NODE CurrentUserDefinedFunction = NULL;
544 OperatorSymbol = ToSymbol(Operator, Error);
545
546#ifdef _SCRIPT_ENGINE_CODEGEN_DBG_EN
547 //
548 // Print Debug Info
549 //
550 printf("Operator :\n");
551 PrintToken(Operator);
552 printf("\n");
553
554 printf("Semantic Stack:\n");
555 PrintTokenList(MatchedStack);
556 printf("\n");
557
558 printf("Code Buffer:\n");
559 PrintSymbolBuffer((PVOID)CodeBuffer);
560 printf(".\n.\n.\n\n");
561#endif
562
563 while (TRUE)
564 {
565 if (IsVariableType(Operator))
566 {
567 PTOKEN PToken = CopyToken(Operator);
568 PToken->Type = INPUT_VARIABLE_TYPE;
569 Push(MatchedStack, PToken);
570 }
571 else if (!strcmp(Operator->Value, "@START_OF_USER_DEFINED_FUNCTION"))
572 {
573 Op0 = Pop(MatchedStack);
574 VariableType = HandleType(MatchedStack);
575
576 if (VariableType == VARIABLE_TYPE_UNKNOWN)
577 {
579 break;
580 }
581
582 //
583 // Add jmp instruction to Code Buffer
584 //
585 PSYMBOL JumpInstruction = NewSymbol();
586 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
587 JumpInstruction->Value = FUNC_JMP;
588 PushSymbol(CodeBuffer, JumpInstruction);
589 RemoveSymbol(&JumpInstruction);
590
591 //
592 // Push jump address
593 //
594
595 PSYMBOL JumpAddressSymbol = NewSymbol();
596 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
597 JumpAddressSymbol->Value = 0xffffffffffffffff;
598 PushSymbol(CodeBuffer, JumpAddressSymbol);
599 RemoveSymbol(&JumpAddressSymbol);
600
601 if (!*UserDefinedFunctionHead)
602 {
603 *UserDefinedFunctionHead = malloc(sizeof(USER_DEFINED_FUNCTION_NODE));
604 RtlZeroMemory(*UserDefinedFunctionHead, sizeof(USER_DEFINED_FUNCTION_NODE));
605 CurrentUserDefinedFunction = *UserDefinedFunctionHead;
606 }
607 else
608 {
609 PUSER_DEFINED_FUNCTION_NODE Node = *UserDefinedFunctionHead;
610 while (Node->NextNode)
611 {
612 Node = Node->NextNode;
613 }
614 Node->NextNode = malloc(sizeof(USER_DEFINED_FUNCTION_NODE));
615 RtlZeroMemory(Node->NextNode, sizeof(USER_DEFINED_FUNCTION_NODE));
616 CurrentUserDefinedFunction = Node->NextNode;
617 }
618
619 CurrentUserDefinedFunction->Name = _strdup(Op0->Value);
620 UINT64 CurrentPointer = CodeBuffer->Pointer;
621 CurrentUserDefinedFunction->Address = CurrentPointer;
622 CurrentUserDefinedFunction->VariableType = (long long unsigned)VariableType;
623
624 //
625 // push stack base index
626 //
627 TempSymbol = NewSymbol();
628 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
629 TempSymbol->Value = FUNC_PUSH;
630 PushSymbol(CodeBuffer, TempSymbol);
631 RemoveSymbol(&TempSymbol);
632
633 TempSymbol = NewSymbol();
635 TempSymbol->Value = 0;
636 PushSymbol(CodeBuffer, TempSymbol);
637 RemoveSymbol(&TempSymbol);
638
639 //
640 // move stack index to stack base index
641 //
642 TempSymbol = NewSymbol();
643 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
644 TempSymbol->Value = FUNC_MOV;
645 PushSymbol(CodeBuffer, TempSymbol);
646 RemoveSymbol(&TempSymbol);
647
648 TempSymbol = NewSymbol();
649 TempSymbol->Type = SYMBOL_STACK_INDEX_TYPE;
650 TempSymbol->Value = 0;
651 PushSymbol(CodeBuffer, TempSymbol);
652 RemoveSymbol(&TempSymbol);
653
654 TempSymbol = NewSymbol();
656 TempSymbol->Value = 0;
657 PushSymbol(CodeBuffer, TempSymbol);
658 RemoveSymbol(&TempSymbol);
659
660 //
661 // add stack index
662 //
663 TempSymbol = NewSymbol();
664 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
665 TempSymbol->Value = FUNC_ADD;
666 PushSymbol(CodeBuffer, TempSymbol);
667 RemoveSymbol(&TempSymbol);
668
669 TempSymbol = NewSymbol();
670 TempSymbol->Type = SYMBOL_NUM_TYPE;
671 TempSymbol->Value = 0xffffffffffffffff;
672 PushSymbol(CodeBuffer, TempSymbol);
673 RemoveSymbol(&TempSymbol);
674
675 TempSymbol = NewSymbol();
676 TempSymbol->Type = SYMBOL_STACK_INDEX_TYPE;
677 TempSymbol->Value = 0;
678 PushSymbol(CodeBuffer, TempSymbol);
679 RemoveSymbol(&TempSymbol);
680
681 TempSymbol = NewSymbol();
682 TempSymbol->Type = SYMBOL_STACK_INDEX_TYPE;
683 TempSymbol->Value = 0;
684 PushSymbol(CodeBuffer, TempSymbol);
685 RemoveSymbol(&TempSymbol);
686 }
687 else if (!strcmp(Operator->Value, "@FUNCTION_PARAMETER"))
688 {
689 Op0 = Pop(MatchedStack);
690 VariableType = HandleType(MatchedStack);
691
692 if (VariableType == VARIABLE_TYPE_UNKNOWN)
693 {
695 break;
696 }
697
698 Op0Symbol = NewSymbol();
699 free((void *)Op0Symbol->Value);
700 Op0Symbol->Value = NewFunctionParameterIdentifier(Op0);
702
703 if (!CurrentUserDefinedFunction->ParameterBuffer)
704 {
705 CurrentUserDefinedFunction->ParameterBuffer = NewSymbolBuffer();
706 }
707 PushSymbol(CurrentUserDefinedFunction->ParameterBuffer, Op0Symbol);
708 CurrentUserDefinedFunction->ParameterNumber++;
709 }
710 else if (!strcmp(Operator->Value, "@END_OF_USER_DEFINED_FUNCTION"))
711 {
712 UINT64 CurrentPointer = CodeBuffer->Pointer;
713 PSYMBOL Symbol = NULL;
714
715 if (!CurrentUserDefinedFunction)
716 {
718 break;
719 }
720 long long unsigned StackTempNumber = 0;
721 for (UINT64 i = CurrentUserDefinedFunction->Address; i < CurrentPointer; i++)
722 {
723 Symbol = CodeBuffer->Head + i;
724 if (Symbol->Type == SYMBOL_STACK_TEMP_TYPE && (Symbol->Value + 1) > StackTempNumber)
725 {
726 StackTempNumber = Symbol->Value + 1;
727 }
728 }
729
730 Symbol = CodeBuffer->Head + CurrentUserDefinedFunction->Address + 6;
731 CurrentUserDefinedFunction->StackTempNumber = Symbol->Value = StackTempNumber;
732
733 //
734 // modify jump address
735 //
736 for (UINT64 i = CurrentUserDefinedFunction->Address; i < CurrentPointer; i++)
737 {
738 Symbol = CodeBuffer->Head + i;
739 if (Symbol->Type == SYMBOL_SEMANTIC_RULE_TYPE && Symbol->Value == FUNC_JMP && (CodeBuffer->Head + i + 1)->Value == 0xfffffffffffffff0)
740 {
741 (CodeBuffer->Head + i + 1)->Value = CurrentPointer;
742 i++;
743 }
744 }
745
746 //
747 // move stack base index to stack index
748 //
749 TempSymbol = NewSymbol();
750 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
751 TempSymbol->Value = FUNC_MOV;
752 PushSymbol(CodeBuffer, TempSymbol);
753 RemoveSymbol(&TempSymbol);
754
755 TempSymbol = NewSymbol();
757 TempSymbol->Value = 0;
758 PushSymbol(CodeBuffer, TempSymbol);
759 RemoveSymbol(&TempSymbol);
760
761 TempSymbol = NewSymbol();
762 TempSymbol->Type = SYMBOL_STACK_INDEX_TYPE;
763 TempSymbol->Value = 0;
764 PushSymbol(CodeBuffer, TempSymbol);
765 RemoveSymbol(&TempSymbol);
766
767 //
768 // pop stack base index
769 //
770 TempSymbol = NewSymbol();
771 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
772 TempSymbol->Value = FUNC_POP;
773 PushSymbol(CodeBuffer, TempSymbol);
774 RemoveSymbol(&TempSymbol);
775
776 TempSymbol = NewSymbol();
778 TempSymbol->Value = 0;
779 PushSymbol(CodeBuffer, TempSymbol);
780 RemoveSymbol(&TempSymbol);
781
782 TempSymbol = NewSymbol();
783 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
784 TempSymbol->Value = FUNC_RET;
785 PushSymbol(CodeBuffer, TempSymbol);
786 RemoveSymbol(&TempSymbol);
787
788 Symbol = CodeBuffer->Head + CurrentUserDefinedFunction->Address - 1;
789 Symbol->Value = CodeBuffer->Pointer;
790
792
793 CurrentUserDefinedFunction = NULL;
794 }
795 else if (!strcmp(Operator->Value, "@RETURN_OF_USER_DEFINED_FUNCTION_WITHOUT_VALUE"))
796 {
797 if (!CurrentUserDefinedFunction)
798 {
800 break;
801 }
802 if (CurrentUserDefinedFunction->VariableType != (unsigned long long)VARIABLE_TYPE_VOID)
803 {
805 break;
806 }
807
808 //
809 // Jump to ret code
810 //
811 PSYMBOL Symbol = NewSymbol();
813 Symbol->Value = FUNC_JMP;
814 PushSymbol(CodeBuffer, Symbol);
815 RemoveSymbol(&Symbol);
816
817 Symbol = NewSymbol();
818 Symbol->Type = SYMBOL_NUM_TYPE;
819 Symbol->Value = 0xfffffffffffffff0;
820 PushSymbol(CodeBuffer, Symbol);
821 RemoveSymbol(&Symbol);
822 }
823 else if (!strcmp(Operator->Value, "@RETURN_OF_USER_DEFINED_FUNCTION_WITH_VALUE"))
824 {
825 if (!CurrentUserDefinedFunction)
826 {
828 break;
829 }
830 if (CurrentUserDefinedFunction->VariableType == (unsigned long long)VARIABLE_TYPE_VOID)
831 {
833 break;
834 }
835
836 //
837 // Store return value
838 //
839 PSYMBOL Symbol = NewSymbol();
841 Symbol->Value = FUNC_MOV;
842 PushSymbol(CodeBuffer, Symbol);
843 RemoveSymbol(&Symbol);
844
845 Op0 = Pop(MatchedStack);
846 Op0Symbol = ToSymbol(Op0, Error);
847 PushSymbol(CodeBuffer, Op0Symbol);
848 FreeTemp(Op0);
849
850 Symbol = NewSymbol();
852 Symbol->Value = 0;
853 PushSymbol(CodeBuffer, Symbol);
854 RemoveSymbol(&Symbol);
855
856 //
857 // Jump to ret code
858 //
859 Symbol = NewSymbol();
861 Symbol->Value = FUNC_JMP;
862 PushSymbol(CodeBuffer, Symbol);
863 RemoveSymbol(&Symbol);
864
865 Symbol = NewSymbol();
866 Symbol->Type = SYMBOL_NUM_TYPE;
867 Symbol->Value = 0xfffffffffffffff0;
868 PushSymbol(CodeBuffer, Symbol);
869 RemoveSymbol(&Symbol);
870
871 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
872 {
873 break;
874 }
875 }
876
877 else if (!strcmp(Operator->Value, "@CALL_USER_DEFINED_FUNCTION"))
878 {
879 PTOKEN FunctionToken = Top(MatchedStack);
880 BOOL Found = FALSE;
881
882 PUSER_DEFINED_FUNCTION_NODE Node = *UserDefinedFunctionHead;
883 while (Node)
884 {
885 if (!strcmp((const char *)FunctionToken->Value, Node->Name))
886 {
887 Found = TRUE;
888 break;
889 }
890 Node = Node->NextNode;
891 }
892
893 if (!Found)
894 {
896 break;
897 }
898
899 FunctionToken->Type = FUNCTION_TYPE;
900 }
901 else if (!strcmp(Operator->Value, "@CALL_USER_DEFINED_FUNCTION_PARAMETER"))
902 {
903 // will rewrite here to input variable's type
904 PSYMBOL TempSymbol = NULL;
905
906 TempSymbol = NewSymbol();
907 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
908 TempSymbol->Value = FUNC_PUSH;
909 PushSymbol(CodeBuffer, TempSymbol);
910 RemoveSymbol(&TempSymbol);
911
912 Op0Symbol = ToSymbol(Top(MatchedStack), Error);
913 PushSymbol(CodeBuffer, Op0Symbol);
914 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
915 {
916 break;
917 }
918 }
919 else if (!strcmp(Operator->Value, "@END_OF_CALLING_USER_DEFINED_FUNCTION_WITHOUT_RETURNING_VALUE") || !strcmp(Operator->Value, "@END_OF_CALLING_USER_DEFINED_FUNCTION_WITH_RETURNING_VALUE"))
920 {
921 PSYMBOL Symbol = NULL;
922 int TargetFunctionVariableNum = 0;
923 int VariableNum = 0;
924 PTOKEN FunctionToken = NULL;
925 BOOL Found = FALSE;
926 PTOKEN ReturnValueToken = NULL;
927
928 while (MatchedStack->Pointer > 0)
929 {
930 FunctionToken = Pop(MatchedStack);
931
932 if (FunctionToken->Type == FUNCTION_TYPE)
933 {
934 break;
935 }
936 else
937 {
938 VariableNum++;
939 // RemoveToken(&FunctionToken);
940 }
941 }
942
943 PUSER_DEFINED_FUNCTION_NODE Node = *UserDefinedFunctionHead;
944 while (Node)
945 {
946 if (!strcmp((const char *)FunctionToken->Value, Node->Name))
947 {
948 Found = TRUE;
949 break;
950 }
951 Node = Node->NextNode;
952 }
953
954 if (!Found)
955 {
957 break;
958 }
959
960 if (VariableNum != Node->ParameterNumber)
961 {
963 break;
964 }
965
966 PSYMBOL TempSymbol = NULL;
967 TempSymbol = NewSymbol();
968 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
969 TempSymbol->Value = FUNC_CALL;
970 PushSymbol(CodeBuffer, TempSymbol);
971 RemoveSymbol(&TempSymbol);
972
973 TempSymbol = NewSymbol();
974 TempSymbol->Type = SYMBOL_NUM_TYPE;
975 TempSymbol->Value = Node->Address;
976 PushSymbol(CodeBuffer, TempSymbol);
977 RemoveSymbol(&TempSymbol);
978
979 TempSymbol = NewSymbol();
980 TempSymbol->Type = SYMBOL_SEMANTIC_RULE_TYPE;
981 TempSymbol->Value = FUNC_SUB;
982 PushSymbol(CodeBuffer, TempSymbol);
983 RemoveSymbol(&TempSymbol);
984
985 TempSymbol = NewSymbol();
986 TempSymbol->Type = SYMBOL_NUM_TYPE;
987 TempSymbol->Value = Node->ParameterNumber;
988 PushSymbol(CodeBuffer, TempSymbol);
989 RemoveSymbol(&TempSymbol);
990
991 TempSymbol = NewSymbol();
992 TempSymbol->Type = SYMBOL_STACK_INDEX_TYPE;
993 PushSymbol(CodeBuffer, TempSymbol);
994 RemoveSymbol(&TempSymbol);
995
996 TempSymbol = NewSymbol();
997 TempSymbol->Type = SYMBOL_STACK_INDEX_TYPE;
998 PushSymbol(CodeBuffer, TempSymbol);
999 RemoveSymbol(&TempSymbol);
1000
1001 if (!strcmp(Operator->Value, "@END_OF_CALLING_USER_DEFINED_FUNCTION_WITH_RETURNING_VALUE"))
1002 {
1003 if (FunctionToken->Type == (TOKEN_TYPE)VARIABLE_TYPE_VOID)
1004 {
1006 break;
1007 }
1008
1009 //
1010 // Add return variable symbol
1011 //
1012 Temp = NewTemp(Error, CurrentUserDefinedFunction);
1013 Push(MatchedStack, Temp);
1014
1015 PSYMBOL Symbol = NewSymbol();
1017 Symbol->Value = FUNC_MOV;
1018 PushSymbol(CodeBuffer, Symbol);
1019 RemoveSymbol(&Symbol);
1020
1021 Symbol = NewSymbol();
1023 Symbol->Value = 0;
1024 PushSymbol(CodeBuffer, Symbol);
1025 RemoveSymbol(&Symbol);
1026
1027 TempSymbol = ToSymbol(Temp, Error);
1028 PushSymbol(CodeBuffer, TempSymbol);
1029
1030 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1031 {
1032 break;
1033 }
1034 }
1035
1036 RemoveToken(&FunctionToken);
1037 }
1038 else if (!strcmp(Operator->Value, "@MOV"))
1039 {
1040 PushSymbol(CodeBuffer, OperatorSymbol);
1041 Op0 = Pop(MatchedStack);
1042 Op0Symbol = ToSymbol(Op0, Error);
1043
1044 Op1 = Pop(MatchedStack);
1045 if (Op1->Type == GLOBAL_UNRESOLVED_ID)
1046 {
1047 Op1Symbol = NewSymbol();
1048 free((void *)Op1Symbol->Value);
1049 Op1Symbol->Value = NewGlobalIdentifier(Op1);
1050 SetType(&Op1Symbol->Type, SYMBOL_GLOBAL_ID_TYPE);
1051 }
1052 else if (Op1->Type == LOCAL_UNRESOLVED_ID)
1053 {
1054 Op1Symbol = NewSymbol();
1055 free((void *)Op1Symbol->Value);
1056 Op1Symbol->Value = NewLocalIdentifier(Op1);
1057 SetType(&Op1Symbol->Type, SYMBOL_LOCAL_ID_TYPE);
1058 }
1059 else
1060 {
1061 Op1Symbol = ToSymbol(Op1, Error);
1062 }
1063
1064 if (MatchedStack->Pointer > 0)
1065 {
1066 if (Top(MatchedStack)->Type == INPUT_VARIABLE_TYPE)
1067 {
1068 VariableType = HandleType(MatchedStack);
1069
1070 if (VariableType == VARIABLE_TYPE_UNKNOWN)
1071 {
1073 break;
1074 }
1075
1076 Op1Symbol->VariableType = (unsigned long long)VariableType;
1077 }
1078 }
1079
1080 PushSymbol(CodeBuffer, Op0Symbol);
1081 PushSymbol(CodeBuffer, Op1Symbol);
1082
1083 //
1084 // Free the operand if it is a temp value
1085 //
1086 FreeTemp(Op0);
1087 FreeTemp(Op1);
1088 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1089 {
1090 break;
1091 }
1092 }
1093 else if (IsType2Func(Operator))
1094 {
1095 PushSymbol(CodeBuffer, OperatorSymbol);
1096 Op0 = Pop(MatchedStack);
1097 Op0Symbol = ToSymbol(Op0, Error);
1098
1099 PushSymbol(CodeBuffer, Op0Symbol);
1100 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1101 {
1102 break;
1103 }
1104 }
1105 else if (IsType1Func(Operator))
1106 {
1107 PushSymbol(CodeBuffer, OperatorSymbol);
1108 Op0 = Pop(MatchedStack);
1109 Op0Symbol = ToSymbol(Op0, Error);
1110
1111 Temp = NewTemp(Error, CurrentUserDefinedFunction);
1112 Push(MatchedStack, Temp);
1113 TempSymbol = ToSymbol(Temp, Error);
1114
1115 PushSymbol(CodeBuffer, Op0Symbol);
1116 PushSymbol(CodeBuffer, TempSymbol);
1117
1118 FreeTemp(Op0);
1119 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1120 {
1121 break;
1122 }
1123 }
1124 else if (IsType4Func(Operator))
1125 {
1126 PushSymbol(CodeBuffer, OperatorSymbol);
1127 PSYMBOL_BUFFER TempStack = NewSymbolBuffer();
1128 UINT32 OperandCount = 0;
1129 do
1130 {
1131 if (Op1)
1132 {
1133 RemoveToken(&Op1);
1134 }
1135 Op1 = Pop(MatchedStack);
1136 if (Op1->Type != SEMANTIC_RULE)
1137 {
1138 Op1Symbol = ToSymbol(Op1, Error);
1139
1140 FreeTemp(Op1);
1141 PushSymbol(TempStack, Op1Symbol);
1142 RemoveSymbol(&Op1Symbol);
1143
1144 OperandCount++;
1145 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1146 {
1147 RemoveSymbolBuffer((PVOID)TempStack);
1148 break;
1149 }
1150 }
1151
1152 } while (!(Op1->Type == SEMANTIC_RULE && !strcmp(Op1->Value, "@VARGSTART")));
1153
1154 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1155 {
1156 break;
1157 }
1158 Op0 = Pop(MatchedStack);
1159 Op0Symbol = ToSymbol(Op0, Error);
1160 FreeTemp(Op0);
1161
1162 char * Format = Op0->Value;
1163
1164 PSYMBOL OperandCountSymbol = NewSymbol();
1165 OperandCountSymbol->Type = SYMBOL_VARIABLE_COUNT_TYPE;
1166 OperandCountSymbol->Value = OperandCount;
1167
1168 PushSymbol(CodeBuffer, Op0Symbol);
1169 PushSymbol(CodeBuffer, OperandCountSymbol);
1170
1171 RemoveSymbol(&OperandCountSymbol);
1172 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1173 {
1174 RemoveSymbolBuffer((PVOID)TempStack);
1175 break;
1176 }
1177
1178 unsigned int FirstArgPointer = CodeBuffer->Pointer;
1179
1180 PSYMBOL Symbol;
1181 unsigned int ArgCount = TempStack->Pointer;
1182 for (int i = TempStack->Pointer - 1; i >= 0; i--)
1183 {
1184 Symbol = TempStack->Head + i;
1185 PushSymbol(CodeBuffer, Symbol);
1186 }
1187 PSYMBOL FirstArg = (PSYMBOL)((unsigned long long)CodeBuffer->Head +
1188 (unsigned long long)(FirstArgPointer * sizeof(SYMBOL)));
1189 RemoveSymbolBuffer((PVOID)TempStack);
1190
1191 UINT32 i = 0;
1192 char * Str = Format;
1193 do
1194 {
1195 //
1196 // Not the best way but some how for optimization
1197 //
1198 if (*Str == '%')
1199 {
1200 CHAR Temp = *(Str + 1);
1201
1202 if (Temp == 'd' || Temp == 'i' || Temp == 'u' || Temp == 'o' ||
1203 Temp == 'x' || Temp == 'c' || Temp == 'p' || Temp == 's' ||
1204
1205 !strncmp(Str, "%ws", 3) || !strncmp(Str, "%ls", 3) ||
1206
1207 !strncmp(Str, "%ld", 3) || !strncmp(Str, "%li", 3) ||
1208 !strncmp(Str, "%lu", 3) || !strncmp(Str, "%lo", 3) ||
1209 !strncmp(Str, "%lx", 3) ||
1210
1211 !strncmp(Str, "%hd", 3) || !strncmp(Str, "%hi", 3) ||
1212 !strncmp(Str, "%hu", 3) || !strncmp(Str, "%ho", 3) ||
1213 !strncmp(Str, "%hx", 3) ||
1214
1215 !strncmp(Str, "%lld", 4) || !strncmp(Str, "%lli", 4) ||
1216 !strncmp(Str, "%llu", 4) || !strncmp(Str, "%llo", 4) ||
1217 !strncmp(Str, "%llx", 4)
1218
1219 )
1220 {
1221 if (i < ArgCount)
1222 {
1223 Symbol = FirstArg + i;
1224 }
1225 else
1226 {
1228 break;
1229 }
1230 Symbol->Type &= 0xffffffff;
1231 Symbol->Type |= (UINT64)(Str - Format - 1) << 32;
1232 i++;
1233 }
1234 }
1235 Str++;
1236 } while (*Str);
1237 if (i != ArgCount)
1238 {
1240 }
1241
1242 if (*Error == SCRIPT_ENGINE_ERROR_SYNTAX)
1243 {
1244 break;
1245 }
1246 }
1247 else if (IsType5Func(Operator))
1248 {
1249 PushSymbol(CodeBuffer, OperatorSymbol);
1250 }
1251 else if (!strcmp(Operator->Value, "@IGNORE_LVALUE"))
1252 {
1253 Op0 = Pop(MatchedStack);
1254 }
1255 else if (IsType6Func(Operator))
1256 {
1257 PushSymbol(CodeBuffer, OperatorSymbol);
1258 Op0 = Pop(MatchedStack);
1259 Op0Symbol = ToSymbol(Op0, Error);
1260
1261 Op1 = Pop(MatchedStack);
1262 Op1Symbol = ToSymbol(Op1, Error);
1263
1264 PushSymbol(CodeBuffer, Op0Symbol);
1265 PushSymbol(CodeBuffer, Op1Symbol);
1266 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1267 {
1268 break;
1269 }
1270
1271 Temp = NewTemp(Error, CurrentUserDefinedFunction);
1272 Push(MatchedStack, Temp);
1273 TempSymbol = ToSymbol(Temp, Error);
1274 PushSymbol(CodeBuffer, TempSymbol);
1275
1276 //
1277 // Free the operand if it is a temp value
1278 //
1279 FreeTemp(Op0);
1280 FreeTemp(Op1);
1281 }
1282 else if (IsType7Func(Operator))
1283 {
1284 PushSymbol(CodeBuffer, OperatorSymbol);
1285 Op0 = Pop(MatchedStack);
1286 Op0Symbol = ToSymbol(Op0, Error);
1287
1288 Op1 = Pop(MatchedStack);
1289 Op1Symbol = ToSymbol(Op1, Error);
1290
1291 PushSymbol(CodeBuffer, Op0Symbol);
1292 PushSymbol(CodeBuffer, Op1Symbol);
1293 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1294 {
1295 break;
1296 }
1297 //
1298 // Free the operand if it is a temp value
1299 //
1300 FreeTemp(Op0);
1301 FreeTemp(Op1);
1302 }
1303 else if (IsType8Func(Operator))
1304 {
1305 PushSymbol(CodeBuffer, OperatorSymbol);
1306 Op0 = Pop(MatchedStack);
1307 Op0Symbol = ToSymbol(Op0, Error);
1308
1309 Op1 = Pop(MatchedStack);
1310 Op1Symbol = ToSymbol(Op1, Error);
1311
1312 Op2 = Pop(MatchedStack);
1313 Op2Symbol = ToSymbol(Op2, Error);
1314
1315 PushSymbol(CodeBuffer, Op0Symbol);
1316 PushSymbol(CodeBuffer, Op1Symbol);
1317 PushSymbol(CodeBuffer, Op2Symbol);
1318
1319 Temp = NewTemp(Error, CurrentUserDefinedFunction);
1320 Push(MatchedStack, Temp);
1321 TempSymbol = ToSymbol(Temp, Error);
1322 PushSymbol(CodeBuffer, TempSymbol);
1323
1324 FreeTemp(Op2);
1325
1326 //
1327 // Free the operand if it is a temp value
1328 //
1329 FreeTemp(Op0);
1330 FreeTemp(Op1);
1331 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1332 {
1333 break;
1334 }
1335 }
1336 else if (IsType14Func(Operator))
1337 {
1338 PushSymbol(CodeBuffer, OperatorSymbol);
1339 Op0 = Pop(MatchedStack);
1340 Op0Symbol = ToSymbol(Op0, Error);
1341
1342 Op1 = Pop(MatchedStack);
1343 Op1Symbol = ToSymbol(Op1, Error);
1344
1345 Op2 = Pop(MatchedStack);
1346 Op2Symbol = ToSymbol(Op2, Error);
1347
1348 PushSymbol(CodeBuffer, Op0Symbol);
1349 PushSymbol(CodeBuffer, Op1Symbol);
1350 PushSymbol(CodeBuffer, Op2Symbol);
1351 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1352 {
1353 break;
1354 }
1355 //
1356 // Free the operand if it is a temp value
1357 //
1358 FreeTemp(Op0);
1359 FreeTemp(Op1);
1360 FreeTemp(Op2);
1361 }
1362 else if (IsTwoOperandOperator(Operator))
1363 {
1364 PushSymbol(CodeBuffer, OperatorSymbol);
1365 Op0 = Pop(MatchedStack);
1366 Op0Symbol = ToSymbol(Op0, Error);
1367
1368 Op1 = Pop(MatchedStack);
1369 Op1Symbol = ToSymbol(Op1, Error);
1370
1371 Temp = NewTemp(Error, CurrentUserDefinedFunction);
1372 Push(MatchedStack, Temp);
1373 TempSymbol = ToSymbol(Temp, Error);
1374
1375 PushSymbol(CodeBuffer, Op0Symbol);
1376 PushSymbol(CodeBuffer, Op1Symbol);
1377 PushSymbol(CodeBuffer, TempSymbol);
1378
1379 //
1380 // Free the operand if it is a temp value
1381 //
1382 FreeTemp(Op0);
1383 FreeTemp(Op1);
1384 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1385 {
1386 break;
1387 }
1388 }
1389 else if (IsOneOperandOperator(Operator))
1390 {
1391 PushSymbol(CodeBuffer, OperatorSymbol);
1392 Op0 = Pop(MatchedStack);
1393 Op0Symbol = ToSymbol(Op0, Error);
1394
1395 PushSymbol(CodeBuffer, Op0Symbol);
1396
1397 //
1398 // Free the operand if it is a temp value
1399 //
1400 FreeTemp(Op0);
1401 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1402 {
1403 break;
1404 }
1405 }
1406 else if (!strcmp(Operator->Value, "@VARGSTART"))
1407 {
1408 PTOKEN OperatorCopy = CopyToken(Operator);
1409 Push(MatchedStack, OperatorCopy);
1410 }
1411 else if (!strcmp(Operator->Value, "@START_OF_IF"))
1412 {
1413 PTOKEN OperatorCopy = CopyToken(Operator);
1414 Push(MatchedStack, OperatorCopy);
1415 }
1416 else if (!strcmp(Operator->Value, "@JZ"))
1417 {
1418 // UINT64 CurrentPointer = CodeBuffer->Pointer;
1419 PushSymbol(CodeBuffer, OperatorSymbol);
1420
1421 PSYMBOL JumpAddressSymbol = NewSymbol();
1422 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
1423 JumpAddressSymbol->Value = 0xffffffffffffffff;
1424 PushSymbol(CodeBuffer, JumpAddressSymbol);
1425 RemoveSymbol(&JumpAddressSymbol);
1426
1427 Op0 = Pop(MatchedStack);
1428 Op0Symbol = ToSymbol(Op0, Error);
1429
1430 PushSymbol(CodeBuffer, Op0Symbol);
1431
1432 char str[20] = {0};
1433 sprintf(str, "%llu", (UINT64)CodeBuffer->Pointer);
1434 PTOKEN CurrentAddressToken = NewToken(DECIMAL, str);
1435 Push(MatchedStack, CurrentAddressToken);
1436
1437 FreeTemp(Op0);
1438 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1439 {
1440 break;
1441 }
1442 }
1443 else if (!strcmp(Operator->Value, "@JMP_TO_END_AND_JZCOMPLETED"))
1444 {
1445 //
1446 // Set JZ jump address
1447 //
1448 UINT64 CurrentPointer = CodeBuffer->Pointer;
1449 PTOKEN JumpSemanticAddressToken = Pop(MatchedStack);
1450 UINT64 JumpSemanticAddress = DecimalToInt(JumpSemanticAddressToken->Value);
1451 PSYMBOL JumpAddressSymbol = (PSYMBOL)(CodeBuffer->Head + JumpSemanticAddress - 2);
1452 JumpAddressSymbol->Value = CurrentPointer + 2;
1453 RemoveToken(&JumpSemanticAddressToken);
1454
1455 //
1456 // Add jmp instruction to Code Buffer
1457 //
1458 PSYMBOL JumpInstruction = NewSymbol();
1459 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
1460 JumpInstruction->Value = FUNC_JMP;
1461 PushSymbol(CodeBuffer, JumpInstruction);
1462 RemoveSymbol(&JumpInstruction);
1463
1464 //
1465 // Add -1 decimal code to jump address
1466 //
1467 JumpAddressSymbol = NewSymbol();
1468 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
1469 JumpAddressSymbol->Value = 0xffffffffffffffff;
1470 PushSymbol(CodeBuffer, JumpAddressSymbol);
1471 RemoveSymbol(&JumpAddressSymbol);
1472
1473 //
1474 // push current pointer to stack
1475 //
1476 char str[20] = {0};
1477 sprintf(str, "%llu", CurrentPointer);
1478 PTOKEN CurrentAddressToken = NewToken(DECIMAL, str);
1479 Push(MatchedStack, CurrentAddressToken);
1480 }
1481 else if (!strcmp(Operator->Value, "@END_OF_IF"))
1482 {
1483 UINT64 CurrentPointer = CodeBuffer->Pointer;
1484 PTOKEN JumpSemanticAddressToken = Pop(MatchedStack);
1485 PSYMBOL JumpAddressSymbol;
1486 while (strcmp(JumpSemanticAddressToken->Value, "@START_OF_IF"))
1487 {
1488 UINT64 JumpSemanticAddress = DecimalToInt(JumpSemanticAddressToken->Value);
1489 JumpAddressSymbol = (PSYMBOL)(CodeBuffer->Head + JumpSemanticAddress + 1);
1490 JumpAddressSymbol->Value = CurrentPointer;
1491
1492 RemoveToken(&JumpSemanticAddressToken);
1493 JumpSemanticAddressToken = Pop(MatchedStack);
1494 }
1495 RemoveToken(&JumpSemanticAddressToken);
1496 }
1497 else if (!strcmp(Operator->Value, "@START_OF_WHILE"))
1498 {
1499 //
1500 // Push @START_OF_WHILE token into matched stack
1501 //
1502 PTOKEN OperatorCopy = CopyToken(Operator);
1503 Push(MatchedStack, OperatorCopy);
1504
1505 char str[20] = {0};
1506 sprintf(str, "%llu", (UINT64)CodeBuffer->Pointer);
1507 PTOKEN CurrentAddressToken = NewToken(DECIMAL, str);
1508 Push(MatchedStack, CurrentAddressToken);
1509 }
1510 else if (!strcmp(Operator->Value, "@START_OF_WHILE_COMMANDS"))
1511 {
1512 UINT64 CurrentPointer = CodeBuffer->Pointer;
1513 PTOKEN JzToken = NewToken(SEMANTIC_RULE, "@JZ");
1514
1515 RemoveSymbol(&OperatorSymbol);
1516 OperatorSymbol = ToSymbol(JzToken, Error);
1517 RemoveToken(&JzToken);
1518
1519 PSYMBOL JumpAddressSymbol = NewSymbol();
1520 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
1521 JumpAddressSymbol->Value = 0xffffffffffffffff;
1522
1523 Op0 = Pop(MatchedStack);
1524 Op0Symbol = ToSymbol(Op0, Error);
1525
1526 PTOKEN StartOfWhileToken = Pop(MatchedStack);
1527
1528 char str[20];
1529 sprintf(str, "%llu", CurrentPointer + 1);
1530 PTOKEN CurrentAddressToken = NewToken(DECIMAL, str);
1531 Push(MatchedStack, CurrentAddressToken);
1532 Push(MatchedStack, StartOfWhileToken);
1533
1534 PushSymbol(CodeBuffer, OperatorSymbol);
1535 PushSymbol(CodeBuffer, JumpAddressSymbol);
1536
1537 PushSymbol(CodeBuffer, Op0Symbol);
1538
1539 RemoveSymbol(&JumpAddressSymbol);
1540
1541 FreeTemp(Op0);
1542 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1543 {
1544 break;
1545 }
1546 }
1547 else if (!strcmp(Operator->Value, "@END_OF_WHILE"))
1548 {
1549 //
1550 // Add jmp instruction to Code Buffer
1551 //
1552 PSYMBOL JumpInstruction = NewSymbol();
1553 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
1554 JumpInstruction->Value = FUNC_JMP;
1555 PushSymbol(CodeBuffer, JumpInstruction);
1556 RemoveSymbol(&JumpInstruction);
1557
1558 //
1559 // Add jmp address to Code buffer
1560 //
1561 PTOKEN JumpAddressToken = Pop(MatchedStack);
1562 UINT64 JumpAddress = DecimalToInt(JumpAddressToken->Value);
1563 PSYMBOL JumpAddressSymbol = ToSymbol(JumpAddressToken, Error);
1564
1565 PushSymbol(CodeBuffer, JumpAddressSymbol);
1566 RemoveSymbol(&JumpAddressSymbol);
1567 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1568 {
1569 break;
1570 }
1571
1572 //
1573 // Set jumps addresses
1574 //
1575
1576 UINT64 CurrentPointer = CodeBuffer->Pointer;
1577
1578 do
1579 {
1580 RemoveToken(&JumpAddressToken);
1581 JumpAddressToken = Pop(MatchedStack);
1582 if (!strcmp(JumpAddressToken->Value, "@START_OF_WHILE"))
1583 {
1584 break;
1585 }
1586 JumpAddress = DecimalToInt(JumpAddressToken->Value);
1587 JumpAddressSymbol = (PSYMBOL)(CodeBuffer->Head + JumpAddress);
1588 JumpAddressSymbol->Value = CurrentPointer;
1589
1590 } while (TRUE);
1591 RemoveToken(&JumpAddressToken);
1592 }
1593 else if (!strcmp(Operator->Value, "@START_OF_DO_WHILE"))
1594 {
1595 //
1596 // Push @START_OF_DO_WHILE token into matched stack
1597 //
1598 PTOKEN OperatorCopy = CopyToken(Operator);
1599 Push(MatchedStack, OperatorCopy);
1600
1601 char str[20];
1602 sprintf(str, "%llu", (UINT64)CodeBuffer->Pointer);
1603 PTOKEN CurrentAddressToken = NewToken(DECIMAL, str);
1604 Push(MatchedStack, CurrentAddressToken);
1605 }
1606 else if (!strcmp(Operator->Value, "@END_OF_DO_WHILE"))
1607 {
1608 //
1609 // Add jmp instruction to Code Buffer
1610 //
1611 PSYMBOL JumpInstruction = NewSymbol();
1612 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
1613 JumpInstruction->Value = FUNC_JNZ;
1614 PushSymbol(CodeBuffer, JumpInstruction);
1615 RemoveSymbol(&JumpInstruction);
1616
1617 //
1618 // Add Op0 to CodeBuffer
1619 //
1620 Op0 = Pop(MatchedStack);
1621 Op0Symbol = ToSymbol(Op0, Error);
1622
1623 //
1624 // Add jmp address to Code buffer
1625 //
1626 PTOKEN JumpAddressToken = Pop(MatchedStack);
1627 UINT64 JumpAddress = DecimalToInt(JumpAddressToken->Value);
1628
1629 PSYMBOL JumpAddressSymbol = ToSymbol(JumpAddressToken, Error);
1630
1631 PushSymbol(CodeBuffer, JumpAddressSymbol);
1632 PushSymbol(CodeBuffer, Op0Symbol);
1633
1634 RemoveSymbol(&JumpAddressSymbol);
1635
1636 FreeTemp(Op0);
1637
1638 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1639 {
1640 break;
1641 }
1642
1643 //
1644 // Set jumps addresses
1645 //
1646
1647 UINT64 CurrentPointer = CodeBuffer->Pointer;
1648
1649 do
1650 {
1651 RemoveToken(&JumpAddressToken);
1652 JumpAddressToken = Pop(MatchedStack);
1653 if (!strcmp(JumpAddressToken->Value, "@START_OF_DO_WHILE"))
1654 {
1655 break;
1656 }
1657 JumpAddress = DecimalToInt(JumpAddressToken->Value);
1658
1659#ifdef _SCRIPT_ENGINE_LL1_DBG_EN
1660 printf("Jz Jump Address = %lld\n", JumpAddress);
1661#endif
1662 JumpAddressSymbol = (PSYMBOL)(CodeBuffer->Head + JumpAddress);
1663 JumpAddressSymbol->Value = CurrentPointer;
1664
1665 } while (TRUE);
1666 RemoveToken(&JumpAddressToken);
1667 }
1668 else if (!strcmp(Operator->Value, "@START_OF_FOR"))
1669 {
1670 //
1671 // Push @START_OF_FOR token into matched stack
1672 //
1673 PTOKEN OperatorCopy = CopyToken(Operator);
1674 Push(MatchedStack, OperatorCopy);
1675
1676 //
1677 // Push current pointer into matched stack
1678 //
1679 char str[20] = {0};
1680 sprintf(str, "%llu", (UINT64)CodeBuffer->Pointer);
1681 PTOKEN CurrentAddressToken = NewToken(DECIMAL, str);
1682 Push(MatchedStack, CurrentAddressToken);
1683 }
1684 else if (!strcmp(Operator->Value, "@FOR_INC_DEC"))
1685 {
1686 //
1687 // JZ
1688 //
1689
1690 //
1691 // Add jz instruction to Code Buffer
1692 //
1693 PSYMBOL JnzInstruction = NewSymbol();
1694 JnzInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
1695 JnzInstruction->Value = FUNC_JZ;
1696 PushSymbol(CodeBuffer, JnzInstruction);
1697 RemoveSymbol(&JnzInstruction);
1698
1699 //
1700 // Add JZ address to Code CodeBuffer
1701 //
1702 PSYMBOL JnzAddressSymbol = NewSymbol();
1703 JnzAddressSymbol->Type = SYMBOL_NUM_TYPE;
1704 JnzAddressSymbol->Value = 0xffffffffffffffff;
1705 PushSymbol(CodeBuffer, JnzAddressSymbol);
1706 RemoveSymbol(&JnzAddressSymbol);
1707
1708 //
1709 // Add Op0 to CodeBuffer
1710 //
1711 Op0 = Pop(MatchedStack);
1712 Op0Symbol = ToSymbol(Op0, Error);
1713
1714 PushSymbol(CodeBuffer, Op0Symbol);
1715 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1716 {
1717 break;
1718 }
1719 //
1720 // JMP
1721 //
1722
1723 //
1724 // Add jmp instruction to Code Buffer
1725 //
1726 PSYMBOL JumpInstruction = NewSymbol();
1727 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
1728 JumpInstruction->Value = FUNC_JMP;
1729 PushSymbol(CodeBuffer, JumpInstruction);
1730 RemoveSymbol(&JumpInstruction);
1731
1732 //
1733 // Add jmp address to Code CodeBuffer
1734 //
1735 PSYMBOL JumpAddressSymbol = NewSymbol();
1736 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
1737 JumpAddressSymbol->Value = 0xffffffffffffffff;
1738 PushSymbol(CodeBuffer, JumpAddressSymbol);
1739 RemoveSymbol(&JumpAddressSymbol);
1740
1741 //
1742 // Pop start_of_for address
1743 //
1744 PTOKEN StartOfForAddressToken = Pop(MatchedStack);
1745
1746 //
1747 // Push current pointer into matched stack
1748 //
1749 char str[20] = {0};
1750 sprintf(str, "%llu", (UINT64)CodeBuffer->Pointer);
1751 PTOKEN CurrentAddressToken = NewToken(DECIMAL, str);
1752 Push(MatchedStack, CurrentAddressToken);
1753
1754 //
1755 // Push start_of_for address to matched stack
1756 //
1757 Push(MatchedStack, StartOfForAddressToken);
1758 }
1759 else if (!strcmp(Operator->Value, "@START_OF_FOR_COMMANDS"))
1760 {
1761 //
1762 // JMP
1763 //
1764
1765 //
1766 // Add jmp instruction to Code Buffer
1767 //
1768 PSYMBOL JumpInstruction = NewSymbol();
1769 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
1770 JumpInstruction->Value = FUNC_JMP;
1771 PushSymbol(CodeBuffer, JumpInstruction);
1772 RemoveSymbol(&JumpInstruction);
1773
1774 //
1775 // Add jmp address to Code buffer
1776 //
1777 PTOKEN JumpAddressToken = Pop(MatchedStack);
1778 UINT64 JumpAddress = DecimalToInt(JumpAddressToken->Value);
1779
1780 PSYMBOL JumpAddressSymbol = ToSymbol(JumpAddressToken, Error);
1781
1782 PushSymbol(CodeBuffer, JumpAddressSymbol);
1783 RemoveToken(&JumpAddressToken);
1784 RemoveSymbol(&JumpAddressSymbol);
1785 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1786 {
1787 break;
1788 }
1789
1790 //
1791 // Set jmp address
1792 //
1793 UINT64 CurrentPointer = CodeBuffer->Pointer;
1794 JumpAddressToken = Pop(MatchedStack);
1795 JumpAddress = DecimalToInt(JumpAddressToken->Value);
1796
1797 JumpAddressSymbol = (PSYMBOL)(CodeBuffer->Head + JumpAddress - 1);
1798 JumpAddressSymbol->Value = CurrentPointer;
1799
1800 //
1801 // Push address of jz address to stack
1802 //
1803 char str[20] = {0};
1804 sprintf(str, "%llu", JumpAddress - 4);
1805 PTOKEN JzAddressToken = NewToken(DECIMAL, str);
1806 Push(MatchedStack, JzAddressToken);
1807
1808 //
1809 // Push @INC_DEC token to matched stack
1810 //
1811 PTOKEN IncDecToken = NewToken(SEMANTIC_RULE, "@INC_DEC");
1812 Push(MatchedStack, IncDecToken);
1813
1814 //
1815 // Push start of inc_dec address to matched stack
1816 //
1817 Push(MatchedStack, JumpAddressToken);
1818 }
1819 else if (!strcmp(Operator->Value, "@END_OF_FOR"))
1820 {
1821 //
1822 // Jmp
1823 //
1824
1825 //
1826 // Add jmp instruction to Code Buffer
1827 //
1828 PSYMBOL JumpInstruction = NewSymbol();
1829 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
1830 JumpInstruction->Value = FUNC_JMP;
1831 PushSymbol(CodeBuffer, JumpInstruction);
1832 RemoveSymbol(&JumpInstruction);
1833
1834 //
1835 // Add jmp address to Code buffer
1836 //
1837 PTOKEN JumpAddressToken = Pop(MatchedStack);
1838 UINT64 JumpAddress = DecimalToInt(JumpAddressToken->Value);
1839
1840 PSYMBOL JumpAddressSymbol = ToSymbol(JumpAddressToken, Error);
1841
1842 PushSymbol(CodeBuffer, JumpAddressSymbol);
1843 RemoveSymbol(&JumpAddressSymbol);
1844 RemoveToken(&JumpAddressToken);
1845
1846 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
1847 {
1848 break;
1849 }
1850
1851 JumpAddressToken = Pop(MatchedStack);
1852
1853 //
1854 // Set jumps addresses
1855 //
1856
1857 UINT64 CurrentPointer = CodeBuffer->Pointer;
1858
1859 do
1860 {
1861 RemoveToken(&JumpAddressToken);
1862 JumpAddressToken = Pop(MatchedStack);
1863 if (!strcmp(JumpAddressToken->Value, "@START_OF_FOR"))
1864 {
1865 break;
1866 }
1867 else
1868 {
1869 JumpAddress = DecimalToInt(JumpAddressToken->Value);
1870
1871 JumpAddressSymbol = (PSYMBOL)(CodeBuffer->Head + JumpAddress);
1872 JumpAddressSymbol->Value = CurrentPointer;
1873 }
1874
1875 } while (TRUE);
1876 RemoveToken(&JumpAddressToken);
1877 }
1878 else if (!strcmp(Operator->Value, "@BREAK"))
1879 {
1880 //
1881 // Pop Objects from stack while reaching @START_OF_*
1882 //
1883
1884 PTOKEN_LIST TempStack = NewTokenList();
1885 PTOKEN TempToken;
1886 do
1887 {
1888 TempToken = Pop(MatchedStack);
1889
1890 if ((!strcmp(TempToken->Value, "@START_OF_FOR")) ||
1891 (!strcmp(TempToken->Value, "@START_OF_WHILE")) ||
1892 (!strcmp(TempToken->Value, "@START_OF_DO_WHILE")))
1893 {
1894 //
1895 // Push back START_OF_*
1896 //
1897 Push(MatchedStack, TempToken);
1898
1899 //
1900 // Push current pointer into matched stack
1901 //
1902
1903 UINT64 CurrentPointer = CodeBuffer->Pointer + 1;
1904 char str[20];
1905 sprintf(str, "%llu", CurrentPointer);
1906 PTOKEN CurrentAddressToken = NewToken(DECIMAL, str);
1907 Push(MatchedStack, CurrentAddressToken);
1908
1909 //
1910 // JMP
1911 //
1912
1913 //
1914 // Add jmp instruction to Code Buffer
1915 //
1916 PSYMBOL JumpInstruction = NewSymbol();
1917 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
1918 JumpInstruction->Value = FUNC_JMP;
1919 PushSymbol(CodeBuffer, JumpInstruction);
1920 RemoveSymbol(&JumpInstruction);
1921
1922 //
1923 // Add jmp address to Code buffer
1924 //
1925 PSYMBOL JumpAddressSymbol = NewSymbol();
1926 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
1927 JumpAddressSymbol->Value = 0xffffffffffffffff;
1928 PushSymbol(CodeBuffer, JumpAddressSymbol);
1929 RemoveSymbol(&JumpAddressSymbol);
1930
1931 //
1932 //
1933 //
1934 do
1935 {
1936 TempToken = Pop(TempStack);
1937 Push(MatchedStack, TempToken);
1938
1939 } while (TempStack->Pointer != 0);
1940 break;
1941 }
1942 else if (MatchedStack->Pointer == 0)
1943 {
1945 RemoveToken(&TempToken);
1946 break;
1947 }
1948 else
1949 {
1950 Push(TempStack, TempToken);
1951 }
1952
1953 } while (TRUE);
1954 RemoveTokenList(TempStack);
1955 }
1956 else if (!strcmp(Operator->Value, "@CONTINUE"))
1957 {
1958 //
1959 // Pop Objects from stack while reaching @INC_DEC
1960 //
1961 PTOKEN_LIST TempStack = NewTokenList();
1962 PTOKEN TempToken;
1963 do
1964 {
1965 TempToken = Pop(MatchedStack);
1966
1967 if (!strcmp(TempToken->Value, "@INC_DEC"))
1968 {
1969 //
1970 // Push back INC_DEC
1971 //
1972 Push(MatchedStack, TempToken);
1973
1974 //
1975 // Add jmp instruction to Code Buffer
1976 //
1977 PSYMBOL JumpInstruction = NewSymbol();
1978 JumpInstruction->Type = SYMBOL_SEMANTIC_RULE_TYPE;
1979 JumpInstruction->Value = FUNC_JMP;
1980 PushSymbol(CodeBuffer, JumpInstruction);
1981 RemoveSymbol(&JumpInstruction);
1982
1983 //
1984 // Add jmp address to Code buffer
1985 //
1986 TempToken = Pop(TempStack);
1987 Push(MatchedStack, TempToken);
1988
1989 PSYMBOL JumpAddressSymbol = NewSymbol();
1990 JumpAddressSymbol->Type = SYMBOL_NUM_TYPE;
1991 JumpAddressSymbol->Value = DecimalToInt(TempToken->Value);
1992 PushSymbol(CodeBuffer, JumpAddressSymbol);
1993 RemoveSymbol(&JumpAddressSymbol);
1994
1995 //
1996 //
1997 //
1998 do
1999 {
2000 TempToken = Pop(TempStack);
2001 Push(MatchedStack, TempToken);
2002
2003 } while (TempStack->Pointer != 0);
2004 break;
2005 }
2006 else if (MatchedStack->Pointer == 0)
2007 {
2009 break;
2010 }
2011 else
2012 {
2013 Push(TempStack, TempToken);
2014 }
2015
2016 } while (TRUE);
2017
2018 RemoveTokenList(TempStack);
2019 }
2020 else if (IsType9Func(Operator))
2021 {
2022 PushSymbol(CodeBuffer, OperatorSymbol);
2023 Op0 = Pop(MatchedStack);
2024 Op0Symbol = ToSymbol(Op0, Error);
2025
2026 Temp = NewTemp(Error, CurrentUserDefinedFunction);
2027 Push(MatchedStack, Temp);
2028 TempSymbol = ToSymbol(Temp, Error);
2029
2030 PushSymbol(CodeBuffer, Op0Symbol);
2031 PushSymbol(CodeBuffer, TempSymbol);
2032
2033 FreeTemp(Op0);
2034 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2035 {
2036 break;
2037 }
2038 }
2039 else if (IsType10Func(Operator))
2040 {
2041 PushSymbol(CodeBuffer, OperatorSymbol);
2042 Op0 = Pop(MatchedStack);
2043 Op0Symbol = ToSymbol(Op0, Error);
2044
2045 Op1 = Pop(MatchedStack);
2046 Op1Symbol = ToSymbol(Op1, Error);
2047
2048 PushSymbol(CodeBuffer, Op0Symbol);
2049 PushSymbol(CodeBuffer, Op1Symbol);
2050 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2051 {
2052 break;
2053 }
2054
2055 Temp = NewTemp(Error, CurrentUserDefinedFunction);
2056 Push(MatchedStack, Temp);
2057 TempSymbol = ToSymbol(Temp, Error);
2058 PushSymbol(CodeBuffer, TempSymbol);
2059
2060 //
2061 // Free the operand if it is a temp value
2062 //
2063 FreeTemp(Op0);
2064 FreeTemp(Op1);
2065 }
2066 else if (IsType11Func(Operator))
2067 {
2068 PushSymbol(CodeBuffer, OperatorSymbol);
2069 Op0 = Pop(MatchedStack);
2070 Op0Symbol = ToSymbol(Op0, Error);
2071
2072 Op1 = Pop(MatchedStack);
2073 Op1Symbol = ToSymbol(Op1, Error);
2074
2075 Op2 = Pop(MatchedStack);
2076 Op2Symbol = ToSymbol(Op2, Error);
2077
2078 PushSymbol(CodeBuffer, Op0Symbol);
2079 PushSymbol(CodeBuffer, Op1Symbol);
2080 PushSymbol(CodeBuffer, Op2Symbol);
2081
2082 Temp = NewTemp(Error, CurrentUserDefinedFunction);
2083 Push(MatchedStack, Temp);
2084 TempSymbol = ToSymbol(Temp, Error);
2085 PushSymbol(CodeBuffer, TempSymbol);
2086
2087 //
2088 // Free the operand if it is a temp value
2089 //
2090 FreeTemp(Op0);
2091 FreeTemp(Op1);
2092 FreeTemp(Op2);
2093 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2094 {
2095 break;
2096 }
2097 }
2098 else if (IsType12Func(Operator))
2099 {
2100 PushSymbol(CodeBuffer, OperatorSymbol);
2101 Op0 = Pop(MatchedStack);
2102 Op0Symbol = ToSymbol(Op0, Error);
2103
2104 Temp = NewTemp(Error, CurrentUserDefinedFunction);
2105 Push(MatchedStack, Temp);
2106 TempSymbol = ToSymbol(Temp, Error);
2107
2108 PushSymbol(CodeBuffer, Op0Symbol);
2109 PushSymbol(CodeBuffer, TempSymbol);
2110
2111 FreeTemp(Op0);
2112 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2113 {
2114 break;
2115 }
2116 }
2117 else if (IsType13Func(Operator))
2118 {
2119 PushSymbol(CodeBuffer, OperatorSymbol);
2120 Op0 = Pop(MatchedStack);
2121 Op0Symbol = ToSymbol(Op0, Error);
2122
2123 Op1 = Pop(MatchedStack);
2124 Op1Symbol = ToSymbol(Op1, Error);
2125
2126 PushSymbol(CodeBuffer, Op0Symbol);
2127 PushSymbol(CodeBuffer, Op1Symbol);
2128 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2129 {
2130 break;
2131 }
2132
2133 Temp = NewTemp(Error, CurrentUserDefinedFunction);
2134 Push(MatchedStack, Temp);
2135 TempSymbol = ToSymbol(Temp, Error);
2136 PushSymbol(CodeBuffer, TempSymbol);
2137
2138 //
2139 // Free the operand if it is a temp value
2140 //
2141 FreeTemp(Op0);
2142 FreeTemp(Op1);
2143 }
2144
2145 else if (IsType15Func(Operator))
2146 {
2147 PushSymbol(CodeBuffer, OperatorSymbol);
2148 Op0 = Pop(MatchedStack);
2149 Op0Symbol = ToSymbol(Op0, Error);
2150
2151 Op1 = Pop(MatchedStack);
2152 Op1Symbol = ToSymbol(Op1, Error);
2153
2154 Op2 = Pop(MatchedStack);
2155 Op2Symbol = ToSymbol(Op2, Error);
2156
2157 PushSymbol(CodeBuffer, Op0Symbol);
2158 PushSymbol(CodeBuffer, Op1Symbol);
2159 PushSymbol(CodeBuffer, Op2Symbol);
2160
2161 Temp = NewTemp(Error, CurrentUserDefinedFunction);
2162 Push(MatchedStack, Temp);
2163 TempSymbol = ToSymbol(Temp, Error);
2164 PushSymbol(CodeBuffer, TempSymbol);
2165
2166 //
2167 // Free the operand if it is a temp value
2168 //
2169 FreeTemp(Op0);
2170 FreeTemp(Op1);
2171 FreeTemp(Op2);
2172 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2173 {
2174 break;
2175 }
2176 }
2177 else
2178 {
2180 }
2181 break;
2182 }
2183
2184#ifdef _SCRIPT_ENGINE_CODEGEN_DBG_EN
2185 //
2186 // Print Debug Info
2187 //
2188 printf("Semantic Stack:\n");
2189 PrintTokenList(MatchedStack);
2190 printf("\n");
2191
2192 printf("Code Buffer:\n");
2193 PrintSymbolBuffer((PVOID)CodeBuffer);
2194 printf("------------------------------------------\n\n");
2195#endif
2196
2197 if (Op0)
2198 RemoveToken(&Op0);
2199
2200 if (Op1)
2201 RemoveToken(&Op1);
2202
2203 if (Op2)
2204 RemoveToken(&Op2);
2205
2206 RemoveSymbol(&OperatorSymbol);
2207
2208 if (Op0Symbol)
2209 RemoveSymbol(&Op0Symbol);
2210
2211 if (Op1Symbol)
2212 RemoveSymbol(&Op1Symbol);
2213
2214 if (Op2Symbol)
2215 RemoveSymbol(&Op2Symbol);
2216
2217 if (TempSymbol)
2218 RemoveSymbol(&TempSymbol);
2219
2220 return;
2221}
int BOOL
Definition BasicTypes.h:23
#define TRUE
Definition BasicTypes.h:55
unsigned int UINT32
Definition BasicTypes.h:48
char CHAR
Definition BasicTypes.h:31
#define SYMBOL_STACK_INDEX_TYPE
Definition ScriptEngineCommonDefinitions.h:69
#define SYMBOL_STACK_TEMP_TYPE
Definition ScriptEngineCommonDefinitions.h:67
#define FUNC_CALL
Definition ScriptEngineCommonDefinitions.h:142
#define SYMBOL_GLOBAL_ID_TYPE
Definition ScriptEngineCommonDefinitions.h:54
#define SYMBOL_LOCAL_ID_TYPE
Definition ScriptEngineCommonDefinitions.h:55
struct SYMBOL * PSYMBOL
#define SYMBOL_FUNCTION_PARAMETER_ID_TYPE
Definition ScriptEngineCommonDefinitions.h:65
#define FUNC_JMP
Definition ScriptEngineCommonDefinitions.h:123
#define FUNC_MOV
Definition ScriptEngineCommonDefinitions.h:131
#define FUNC_SUB
Definition ScriptEngineCommonDefinitions.h:112
#define FUNC_POP
Definition ScriptEngineCommonDefinitions.h:141
#define SYMBOL_STACK_BASE_INDEX_TYPE
Definition ScriptEngineCommonDefinitions.h:70
#define SYMBOL_VARIABLE_COUNT_TYPE
Definition ScriptEngineCommonDefinitions.h:62
#define FUNC_RET
Definition ScriptEngineCommonDefinitions.h:143
#define FUNC_PUSH
Definition ScriptEngineCommonDefinitions.h:140
#define FUNC_ADD
Definition ScriptEngineCommonDefinitions.h:111
#define FUNC_JZ
Definition ScriptEngineCommonDefinitions.h:124
#define SYMBOL_SEMANTIC_RULE_TYPE
Definition ScriptEngineCommonDefinitions.h:59
#define SYMBOL_RETURN_VALUE_TYPE
Definition ScriptEngineCommonDefinitions.h:71
#define SYMBOL_NUM_TYPE
Definition ScriptEngineCommonDefinitions.h:56
#define FUNC_JNZ
Definition ScriptEngineCommonDefinitions.h:125
RequestedActionOfThePacket Value(0x1) 00000000
NULL()
Definition test-case-generator.py:530
char IsType6Func(PTOKEN Operator)
Checks whether this Token type is TwoOpFunc1.
Definition common.c:858
PTOKEN Pop(PTOKEN_LIST TokenList)
Removes last Token of a TokenList and returns it.
Definition common.c:485
PTOKEN Top(PTOKEN_LIST TokenList)
Returns last Token of a TokenList.
Definition common.c:506
char IsType2Func(PTOKEN Operator)
Checks whether this Token type is OneOpFunc2.
Definition common.c:758
char IsType10Func(PTOKEN Operator)
Checks whether this Token type is TwoOpFunc3.
Definition common.c:938
char IsType1Func(PTOKEN Operator)
Checks whether this Token type is OneOpFunc1.
Definition common.c:738
char IsType9Func(PTOKEN Operator)
Checks whether this Token type is OneOpFunc3.
Definition common.c:918
char IsType11Func(PTOKEN Operator)
Checks whether this Token type is ThreeOpFunc3.
Definition common.c:958
void PrintTokenList(PTOKEN_LIST TokenList)
Prints each Token inside a TokenList.
Definition common.c:406
char IsType4Func(PTOKEN Operator)
Checks whether this Token type is VarArgFunc1.
Definition common.c:818
char IsType15Func(PTOKEN Operator)
Checks whether this Token type is ThreeOpFunc4.
Definition common.c:1038
void SetType(unsigned long long *Val, unsigned char Type)
Set the Type object.
Definition common.c:1381
char IsOneOperandOperator(PTOKEN Operator)
Checks whether this Token type is OperatorsOneOperandList.
Definition common.c:798
void FreeTemp(PTOKEN Temp)
Frees the memory allocated by Temp.
Definition common.c:691
char IsType12Func(PTOKEN Operator)
Checks whether this Token type is OneOpFunc4.
Definition common.c:978
void RemoveTokenList(PTOKEN_LIST TokenList)
Removes allocated memory of a TOKEN_LIST.
Definition common.c:386
char IsType8Func(PTOKEN Operator)
Checks whether this Token type is ThreeOpFunc1.
Definition common.c:898
unsigned long long DecimalToInt(char *str)
Converts an decimal string to a integer.
Definition common.c:1393
void RemoveToken(PTOKEN *Token)
Removes allocated memory of a token.
Definition common.c:104
PTOKEN NewTemp(PSCRIPT_ENGINE_ERROR_TYPE Error, PUSER_DEFINED_FUNCTION_NODE CurrentFunctionSymbol)
Allocates a new temporary variable and returns it.
Definition common.c:621
PTOKEN_LIST Push(PTOKEN_LIST TokenList, PTOKEN Token)
Adds Token to the last empty position of TokenList.
Definition common.c:424
char IsType13Func(PTOKEN Operator)
Checks whether this Token type is TwoOpFunc4.
Definition common.c:998
PTOKEN CopyToken(PTOKEN Token)
Copies a PTOKEN.
Definition common.c:312
char IsVariableType(PTOKEN Operator)
Checks whether this Token type is VariableType.
Definition common.c:1059
char IsType14Func(PTOKEN Operator)
Checks whether this Token type is ThreeOpFunc2.
Definition common.c:1018
char IsType5Func(PTOKEN Operator)
Checks whether this Token type is ZeroOpFunc1.
Definition common.c:838
void CleanStackTempList(void)
Resets the stack temporary variables map.
Definition common.c:723
PTOKEN NewToken(TOKEN_TYPE Type, char *Value)
Definition common.c:60
char IsType7Func(PTOKEN Operator)
Checks whether this Token type is TwoOpFunc2.
Definition common.c:878
char IsTwoOperandOperator(PTOKEN Operator)
Checks whether this Token type is OperatorsTwoOperandList.
Definition common.c:778
PTOKEN_LIST NewTokenList(void)
Definition common.c:349
void PrintToken(PTOKEN Token)
Prints token @detail prints value and type of token.
Definition common.c:119
TOKEN_TYPE
enumerates possible types for token
Definition common.h:37
@ INPUT_VARIABLE_TYPE
Definition common.h:60
@ LOCAL_UNRESOLVED_ID
Definition common.h:39
@ FUNCTION_TYPE
Definition common.h:62
@ SEMANTIC_RULE
Definition common.h:54
@ GLOBAL_UNRESOLVED_ID
Definition common.h:41
@ DECIMAL
Definition common.h:42
@ SCRIPT_ENGINE_ERROR_UNDEFINED_FUNCTION
Definition script-engine.h:59
@ SCRIPT_ENGINE_ERROR_NON_VOID_FUNCTION_NOT_RETURNING_VALUE
Definition script-engine.h:62
@ SCRIPT_ENGINE_ERROR_UNHANDLED_SEMANTIC_RULE
Definition script-engine.h:57
@ SCRIPT_ENGINE_ERROR_UNDEFINED_VARIABLE_TYPE
Definition script-engine.h:60
@ SCRIPT_ENGINE_ERROR_VOID_FUNCTION_RETURNING_VALUE
Definition script-engine.h:61
@ SCRIPT_ENGINE_ERROR_SYNTAX
Definition script-engine.h:54
@ SCRIPT_ENGINE_ERROR_FREE
Definition script-engine.h:53
PSYMBOL_BUFFER PushSymbol(PSYMBOL_BUFFER SymbolBuffer, const PSYMBOL Symbol)
Gets a symbol and push it into the symbol buffer.
Definition script-engine.c:2742
void PrintSymbolBuffer(const PVOID SymbolBuffer)
Prints a symbol buffer.
Definition script-engine.c:2859
int NewGlobalIdentifier(PTOKEN Token)
Allocates a new global variable and returns the integer assigned to it.
Definition script-engine.c:3180
PSYMBOL ToSymbol(PTOKEN Token, PSCRIPT_ENGINE_ERROR_TYPE Error)
Converts Token to Symbol and returns the reference to it.
Definition script-engine.c:2612
PSYMBOL NewSymbol(void)
Allocates a new SYMBOL and returns the reference to it.
Definition script-engine.c:2460
int NewLocalIdentifier(PTOKEN Token)
Allocates a new local variable and returns the integer assigned to it.
Definition script-engine.c:3194
int NewFunctionParameterIdentifier(PTOKEN Token)
Definition script-engine.c:3208
void RemoveSymbolBuffer(PVOID SymbolBuffer)
Frees the memory allocated by SymbolBuffer.
Definition script-engine.c:2725
void RemoveSymbol(PSYMBOL *Symbol)
Frees the memory allocate by this Symbol.
Definition script-engine.c:2561
PSYMBOL_BUFFER NewSymbolBuffer(void)
allocates a new Symbol Buffer and returns the reference to it
Definition script-engine.c:2699
this structure is a dynamic container of TOKENS
Definition common.h:83
unsigned int Pointer
Definition common.h:85
read tokens from input stored in this structure
Definition common.h:72
TOKEN_TYPE Type
Definition common.h:73
Definition ScriptEngineCommonDefinitions.h:21
unsigned int Pointer
Definition ScriptEngineCommonDefinitions.h:23
PSYMBOL Head
Definition ScriptEngineCommonDefinitions.h:22
Definition ScriptEngineCommonDefinitions.h:6
long long unsigned Value
Definition ScriptEngineCommonDefinitions.h:10
long long unsigned VariableType
Definition ScriptEngineCommonDefinitions.h:9
long long unsigned Type
Definition ScriptEngineCommonDefinitions.h:7
Definition ScriptEngineCommonDefinitions.h:43
long long unsigned ParameterNumber
Definition ScriptEngineCommonDefinitions.h:48
long long unsigned StackTempNumber
Definition ScriptEngineCommonDefinitions.h:49
char * Name
Definition ScriptEngineCommonDefinitions.h:44
struct USER_DEFINED_FUNCTION_NODE * NextNode
Definition ScriptEngineCommonDefinitions.h:50
long long unsigned Address
Definition ScriptEngineCommonDefinitions.h:45
long long unsigned VariableType
Definition ScriptEngineCommonDefinitions.h:46
PSYMBOL_BUFFER ParameterBuffer
Definition ScriptEngineCommonDefinitions.h:47
Definition type.h:28
VARIABLE_TYPE * HandleType(PTOKEN_LIST PtokenStack)
Return a variable type.
Definition type.c:28
VARIABLE_TYPE * VARIABLE_TYPE_UNKNOWN
Definition type.c:3
VARIABLE_TYPE * VARIABLE_TYPE_VOID
Definition type.c:5

◆ FuncGetNumberOfOperands()

BOOLEAN FuncGetNumberOfOperands ( UINT64 FuncType,
UINT32 * NumberOfGetOperands,
UINT32 * NumberOfSetOperands )

Script Engine get number of operands.

Parameters
FuncType
NumberOfGetOperands
NumberOfSetOperands
BOOLEANWhether the function is defined or not
3357{
3358 BOOLEAN Result = FALSE;
3359
3360 switch (FuncType)
3361 {
3362 case FUNC_INC:
3363
3366 Result = TRUE;
3367
3368 break;
3369
3370 case FUNC_DEC:
3371
3374 Result = TRUE;
3375
3376 break;
3377
3378 case FUNC_OR:
3379
3382 Result = TRUE;
3383
3384 break;
3385
3386 case FUNC_XOR:
3387
3390 Result = TRUE;
3391
3392 break;
3393
3394 case FUNC_AND:
3395
3398 Result = TRUE;
3399
3400 break;
3401
3402 case FUNC_ASL:
3403
3406 Result = TRUE;
3407
3408 break;
3409
3410 case FUNC_ADD:
3411
3414 Result = TRUE;
3415
3416 break;
3417
3418 case FUNC_SUB:
3419
3422 Result = TRUE;
3423
3424 break;
3425
3426 case FUNC_MUL:
3427
3430 Result = TRUE;
3431
3432 break;
3433
3434 case FUNC_DIV:
3435
3438 Result = TRUE;
3439
3440 break;
3441
3442 case FUNC_MOD:
3443
3446 Result = TRUE;
3447
3448 break;
3449
3450 case FUNC_GT:
3451
3454 Result = TRUE;
3455
3456 break;
3457
3458 case FUNC_LT:
3459
3462 Result = TRUE;
3463
3464 break;
3465
3466 case FUNC_EGT:
3467
3470 Result = TRUE;
3471
3472 break;
3473
3474 case FUNC_ELT:
3475
3478 Result = TRUE;
3479
3480 break;
3481
3482 case FUNC_EQUAL:
3483
3486 Result = TRUE;
3487
3488 break;
3489
3490 case FUNC_NEQ:
3491
3494 Result = TRUE;
3495
3496 break;
3497
3498 case FUNC_JMP:
3499
3502 Result = TRUE;
3503
3504 break;
3505
3506 case FUNC_JZ:
3507
3510 Result = TRUE;
3511
3512 break;
3513
3514 case FUNC_JNZ:
3515
3518 Result = TRUE;
3519
3520 break;
3521
3522 case FUNC_MOV:
3523
3526 Result = TRUE;
3527
3528 break;
3529
3530 default:
3531 //
3532 // Not defined
3533 //
3534 Result = FALSE;
3535 break;
3536 }
3537
3538 return Result;
3539}
UCHAR BOOLEAN
Definition BasicTypes.h:39
UINT32 * NumberOfGetOperands
Definition HyperDbgScriptImports.h:33
UINT32 UINT32 * NumberOfSetOperands
Definition HyperDbgScriptImports.h:33
#define FUNC_MUL
Definition ScriptEngineCommonDefinitions.h:113
#define FUNC_GT
Definition ScriptEngineCommonDefinitions.h:116
#define FUNC_EGT
Definition ScriptEngineCommonDefinitions.h:118
#define FUNC_INC
Definition ScriptEngineCommonDefinitions.h:102
#define FUNC_ASL
Definition ScriptEngineCommonDefinitions.h:110
#define FUNC_ELT
Definition ScriptEngineCommonDefinitions.h:119
#define FUNC_OR
Definition ScriptEngineCommonDefinitions.h:106
#define FUNC_XOR
Definition ScriptEngineCommonDefinitions.h:107
#define FUNC_NEQ
Definition ScriptEngineCommonDefinitions.h:121
#define FUNC_EQUAL
Definition ScriptEngineCommonDefinitions.h:120
#define FUNC_LT
Definition ScriptEngineCommonDefinitions.h:117
#define FUNC_DIV
Definition ScriptEngineCommonDefinitions.h:114
#define FUNC_AND
Definition ScriptEngineCommonDefinitions.h:108
#define FUNC_DEC
Definition ScriptEngineCommonDefinitions.h:103
#define FUNC_MOD
Definition ScriptEngineCommonDefinitions.h:115

◆ GetFunctionParameterIdentifier()

int GetFunctionParameterIdentifier ( PTOKEN Token)
Parameters
Token
Returns
int
3223{
3224 PTOKEN CurrentToken;
3225 for (uintptr_t i = 0; i < FunctionParameterIdTable->Pointer; i++)
3226 {
3227 CurrentToken = *(FunctionParameterIdTable->Head + i);
3228 if (!strcmp(Token->Value, CurrentToken->Value))
3229 {
3230 return (int)i;
3231 }
3232 }
3233 return -1;
3234}
PTOKEN_LIST FunctionParameterIdTable
Definition scanner.h:25
PTOKEN * Head
Definition common.h:84

◆ GetGlobalIdentifierVal()

int GetGlobalIdentifierVal ( PTOKEN Token)

Returns the integer assigned to global variable.

Parameters
Token
Returns
int
3139{
3140 PTOKEN CurrentToken;
3141 for (uintptr_t i = 0; i < IdTable->Pointer; i++)
3142 {
3143 CurrentToken = *(IdTable->Head + i);
3144 if (!strcmp(Token->Value, CurrentToken->Value))
3145 {
3146 return (int)i;
3147 }
3148 }
3149 return -1;
3150}
PTOKEN_LIST IdTable
lookup table for storing Ids
Definition scanner.h:20

◆ GetLocalIdentifierVal()

int GetLocalIdentifierVal ( PTOKEN Token)

Returns the integer assigned to local variable.

Parameters
Token
Returns
int
3160{
3161 PTOKEN CurrentToken;
3162 for (uintptr_t i = 0; i < IdTable->Pointer; i++)
3163 {
3164 CurrentToken = *(IdTable->Head + i);
3165 if (!strcmp(Token->Value, CurrentToken->Value))
3166 {
3167 return (int)i;
3168 }
3169 }
3170 return -1;
3171}

◆ GetSymbolHeapSize()

unsigned int GetSymbolHeapSize ( PSYMBOL Symbol)

Returns the number of SYMBOL objects (24 bytes) allocated by string or wstring sybmol.

Returns
PSYMBOL
Parameters
Symbol
Returns
unsigned int
2550{
2551 int Temp = (3 * sizeof(unsigned long long) + (int)Symbol->Len) / sizeof(SYMBOL) + 1;
2552 return Temp;
2553}
long long unsigned Len
Definition ScriptEngineCommonDefinitions.h:8

◆ HandleError()

char * HandleError ( PSCRIPT_ENGINE_ERROR_TYPE Error,
char * str )

Prints some information about the error.

Parameters
Error
str
Returns
char*
3029{
3030 //
3031 // calculate position of current line
3032 //
3033 unsigned int LineEnd;
3034 for (int i = InputIdx;; i++)
3035 {
3036 if (str[i] == '\n' || str[i] == '\0')
3037 {
3038 LineEnd = i;
3039 break;
3040 }
3041 }
3042
3043 //
3044 // allocate required memory for message, 16 for line, 100 for error information,
3045 // (CurrentTokenIdx - CurrentLineIdx) for space and,
3046 // (LineEnd - CurrentLineIdx) for input string
3047 //
3048 int MessageSize = 16 + 100 + (CurrentTokenIdx - CurrentLineIdx) + (LineEnd - CurrentLineIdx);
3049 char * Message = (char *)malloc(MessageSize);
3050
3051 if (Message == NULL)
3052 {
3053 printf("err, could not allocate buffer");
3054 return NULL;
3055 }
3056
3057 //
3058 // add line number
3059 //
3060 strcpy(Message, "Line ");
3061 char Line[16] = {0};
3062 sprintf(Line, "%d:\n", CurrentLine);
3063 strcat(Message, Line);
3064
3065 //
3066 // add the line which error happened at
3067 //
3068 strncat(Message, (str + CurrentLineIdx), LineEnd - CurrentLineIdx);
3069
3070 strcat(Message, "\n");
3071
3072 //
3073 // add pointer
3074 //
3075 char Space = ' ';
3076 int n = (CurrentTokenIdx - CurrentLineIdx);
3077 for (int i = 0; i < n; i++)
3078 {
3079 strncat(Message, &Space, 1);
3080 }
3081 strcat(Message, "^\n");
3082
3083 //
3084 // add error cause and details
3085 //
3086 switch (*Error)
3087 {
3089 strcat(Message, "Syntax Error: ");
3090 strcat(Message, "Invalid Syntax");
3091 return Message;
3092
3094 strcat(Message, "Syntax Error: ");
3095 strcat(Message, "Unknown Token");
3096 return Message;
3097
3099 strcat(Message, "Syntax Error: ");
3100 strcat(Message, "Unresolved Variable");
3101 return Message;
3102
3104 strcat(Message, "Syntax Error: ");
3105 strcat(Message, "Unhandled Semantic Rule");
3106 return Message;
3107
3109 strcat(Message, "Internal Error: ");
3110 strcat(Message, "Please split the expression to many smaller expressions.");
3111 return Message;
3112
3114 strcat(Message, "Undefined Function");
3115 return Message;
3117 strcat(Message, "Undefined Variable Type");
3118 return Message;
3120 strcat(Message, "Returning a value in void function");
3121 return Message;
3123 strcat(Message, "Not returning a value in noo-void function");
3124 return Message;
3125 default:
3126 strcat(Message, "Unknown Error: ");
3127 return Message;
3128 }
3129}
unsigned int CurrentTokenIdx
Definition scanner.h:45
unsigned int CurrentLine
number of current reading line
Definition scanner.h:35
unsigned int CurrentLineIdx
Definition scanner.h:40
@ SCRIPT_ENGINE_ERROR_UNRESOLVED_VARIABLE
Definition script-engine.h:56
@ SCRIPT_ENGINE_ERROR_UNKNOWN_TOKEN
Definition script-engine.h:55
@ SCRIPT_ENGINE_ERROR_TEMP_LIST_FULL
Definition script-engine.h:58

◆ LalrGetRhsSize()

int LalrGetRhsSize ( int RuleId)

Returns the size of Right Hand Side (RHS) of a rule.

Parameters
RuleId
Returns
int
3244{
3245 int Counter = 0;
3246 int N = LalrRhsSize[RuleId];
3247 for (int i = 0; i < N; i++)
3248 {
3249 if (LalrRhs[RuleId][i].Type != EPSILON && LalrRhs[RuleId][i].Type != SEMANTIC_RULE)
3250 {
3251 Counter++;
3252 }
3253 }
3254 return Counter;
3255}
const struct _TOKEN LalrRhs[RULES_COUNT][MAX_RHS_LEN]
Definition parse-table.c:1418
const unsigned int LalrRhsSize[RULES_COUNT]
Definition parse-table.c:1508
@ EPSILON
Definition common.h:56

◆ LalrIsOperandType()

BOOL LalrIsOperandType ( PTOKEN Token)

Returns TRUE if the Token can be the operand of an operator.

Parameters
Token
Returns
BOOL
3265{
3266 if (Token->Type == GLOBAL_ID)
3267 {
3268 return TRUE;
3269 }
3270 else if (Token->Type == GLOBAL_UNRESOLVED_ID)
3271 {
3272 return TRUE;
3273 }
3274 if (Token->Type == LOCAL_ID)
3275 {
3276 return TRUE;
3277 }
3278 else if (Token->Type == LOCAL_UNRESOLVED_ID)
3279 {
3280 return TRUE;
3281 }
3282 else if (Token->Type == FUNCTION_PARAMETER_ID)
3283 {
3284 return TRUE;
3285 }
3286 else if (Token->Type == DECIMAL)
3287 {
3288 return TRUE;
3289 }
3290 else if (Token->Type == HEX)
3291 {
3292 return TRUE;
3293 }
3294 else if (Token->Type == OCTAL)
3295 {
3296 return TRUE;
3297 }
3298 else if (Token->Type == BINARY)
3299 {
3300 return TRUE;
3301 }
3302 else if (Token->Type == REGISTER)
3303 {
3304 return TRUE;
3305 }
3306 else if (Token->Type == PSEUDO_REGISTER)
3307 {
3308 return TRUE;
3309 }
3310 else if (Token->Type == TEMP)
3311 {
3312 return TRUE;
3313 }
3314 else if (Token->Type == STRING)
3315 {
3316 return TRUE;
3317 }
3318 else if (Token->Type == WSTRING)
3319 {
3320 return TRUE;
3321 }
3322 return FALSE;
3323}
@ TEMP
Definition common.h:57
@ LOCAL_ID
Definition common.h:38
@ PSEUDO_REGISTER
Definition common.h:52
@ WSTRING
Definition common.h:59
@ REGISTER
Definition common.h:51
@ OCTAL
Definition common.h:45
@ HEX
Definition common.h:44
@ GLOBAL_ID
Definition common.h:40
@ FUNCTION_PARAMETER_ID
Definition common.h:63
@ BINARY
Definition common.h:46
@ STRING
Definition common.h:58

◆ NewFunctionParameterIdentifier()

int NewFunctionParameterIdentifier ( PTOKEN Token)
Parameters
Token
Returns
int
3209{
3210 PTOKEN CopiedToken = CopyToken(Token);
3213}

◆ NewGlobalIdentifier()

int NewGlobalIdentifier ( PTOKEN Token)

Allocates a new global variable and returns the integer assigned to it.

Parameters
Token
Returns
int
3181{
3182 PTOKEN CopiedToken = CopyToken(Token);
3183 IdTable = Push(IdTable, CopiedToken);
3184 return IdTable->Pointer - 1;
3185}

◆ NewLocalIdentifier()

int NewLocalIdentifier ( PTOKEN Token)

Allocates a new local variable and returns the integer assigned to it.

Parameters
Token
Returns
int
3195{
3196 PTOKEN CopiedToken = CopyToken(Token);
3197 IdTable = Push(IdTable, CopiedToken);
3198 return IdTable->Pointer - 1;
3199}

◆ NewStringSymbol()

PSYMBOL NewStringSymbol ( PTOKEN Token)

Allocates a new SYMBOL with string type and returns the reference to it.

Parameters
value
Returns
PSYMBOL
2488{
2489 PSYMBOL Symbol;
2490 int BufferSize = (3 * sizeof(unsigned long long) + Token->Len) / sizeof(SYMBOL) + 1;
2491 Symbol = (PSYMBOL)calloc(sizeof(SYMBOL), BufferSize);
2492
2493 if (Symbol == NULL)
2494 {
2495 //
2496 // There was an error allocating buffer
2497 //
2498 return NULL;
2499 }
2500
2501 memcpy(&Symbol->Value, Token->Value, Token->Len);
2502 SetType(&Symbol->Type, SYMBOL_STRING_TYPE);
2503 Symbol->Len = Token->Len;
2504 Symbol->VariableType = 0;
2505 return Symbol;
2506}
struct SYMBOL SYMBOL
#define SYMBOL_STRING_TYPE
Definition ScriptEngineCommonDefinitions.h:61
unsigned int Len
Definition common.h:75

◆ NewSymbol()

PSYMBOL NewSymbol ( void )

Allocates a new SYMBOL and returns the reference to it.

Returns
PSYMBOL
2461{
2462 PSYMBOL Symbol;
2463 Symbol = (PSYMBOL)malloc(sizeof(SYMBOL));
2464
2465 if (Symbol == NULL)
2466 {
2467 //
2468 // There was an error allocating buffer
2469 //
2470 return NULL;
2471 }
2472
2473 Symbol->Value = 0;
2474 Symbol->Len = 0;
2475 Symbol->Type = 0;
2476 Symbol->VariableType = 0;
2477 return Symbol;
2478}

◆ NewSymbolBuffer()

PSYMBOL_BUFFER NewSymbolBuffer ( void )

allocates a new Symbol Buffer and returns the reference to it

Returns
PSYMBOL_BUFFER
2700{
2701 PSYMBOL_BUFFER SymbolBuffer;
2702 SymbolBuffer = (PSYMBOL_BUFFER)malloc(sizeof(*SymbolBuffer));
2703
2704 if (SymbolBuffer == NULL)
2705 {
2706 //
2707 // There was an error allocating buffer
2708 //
2709 return NULL;
2710 }
2711
2712 SymbolBuffer->Pointer = 0;
2713 SymbolBuffer->Size = SYMBOL_BUFFER_INIT_SIZE;
2714 SymbolBuffer->Head = (PSYMBOL)malloc(SymbolBuffer->Size * sizeof(SYMBOL));
2715 SymbolBuffer->Message = NULL;
2716 return SymbolBuffer;
2717}
struct SYMBOL_BUFFER * PSYMBOL_BUFFER
#define SYMBOL_BUFFER_INIT_SIZE
Definition common.h:21
char * Message
Definition ScriptEngineCommonDefinitions.h:25
unsigned int Size
Definition ScriptEngineCommonDefinitions.h:24

◆ NewWstringSymbol()

PSYMBOL NewWstringSymbol ( PTOKEN Token)

Allocates a new SYMBOL with wstring type and returns the reference to it.

Parameters
value
Returns
PSYMBOL
2516{
2517 PSYMBOL Symbol;
2518 int BufferSize = (3 * sizeof(unsigned long long) + Token->Len) / sizeof(SYMBOL) + 1;
2519 Symbol = (PSYMBOL)malloc(BufferSize * sizeof(SYMBOL));
2520
2521 if (Symbol == NULL)
2522 {
2523 //
2524 // There was an error allocating buffer
2525 //
2526 return NULL;
2527 }
2528
2529 memcpy(&Symbol->Value, Token->Value, Token->Len);
2530 SetType(&Symbol->Type, SYMBOL_WSTRING_TYPE);
2531 Symbol->Len = Token->Len;
2532 Symbol->VariableType = 0;
2533 return Symbol;
2534}
#define SYMBOL_WSTRING_TYPE
Definition ScriptEngineCommonDefinitions.h:64

◆ PrintSymbol()

void PrintSymbol ( PVOID Symbol)

Prints symbol.

Parameters
PVOID
2575{
2576 PSYMBOL Sym = (PSYMBOL)Symbol;
2577
2578 if (Sym->Type & 0xffffffff00000000)
2579 {
2580 printf("Type = @VARGSTART\n");
2581 return;
2582 }
2583
2584 printf("Type = %s, ", SymbolTypeNames[Sym->Type]);
2585
2586 if (Sym->Type == SYMBOL_SEMANTIC_RULE_TYPE)
2587 {
2588 printf("Value = %s\n", FunctionNames[Sym->Value]);
2589 }
2590 else if (Sym->Type == SYMBOL_STRING_TYPE)
2591 {
2592 printf("Value = %s\n", (char *)&Sym->Value);
2593 }
2594 else if (Sym->Type == SYMBOL_WSTRING_TYPE)
2595 {
2596 printf("Value = %ls\n", (wchar_t *)&Sym->Value);
2597 }
2598 else
2599 {
2600 printf("Value = %lld\n", Sym->Value);
2601 }
2602}

◆ PrintSymbolBuffer()

void PrintSymbolBuffer ( const PVOID SymbolBuffer)

Prints a symbol buffer.

Parameters
SymbolBuffer
2860{
2861 PSYMBOL_BUFFER SymBuff = (PSYMBOL_BUFFER)SymbolBuffer;
2862 PSYMBOL Symbol;
2863 printf("CodeBuffer:\n");
2864 for (unsigned int i = 0; i < SymBuff->Pointer;)
2865 {
2866 Symbol = SymBuff->Head + i;
2867 printf("Address = %d, ", i);
2868 PrintSymbol((PVOID)Symbol);
2869 if (Symbol->Type == SYMBOL_STRING_TYPE || Symbol->Type == SYMBOL_WSTRING_TYPE)
2870 {
2871 int temp = GetSymbolHeapSize(Symbol);
2872 i += temp;
2873 }
2874 else
2875 {
2876 i++;
2877 }
2878 }
2879}
void PrintSymbol(PVOID Symbol)
Prints symbol.
Definition script-engine.c:2574
unsigned int GetSymbolHeapSize(PSYMBOL Symbol)
Returns the number of SYMBOL objects (24 bytes) allocated by string or wstring sybmol.
Definition script-engine.c:2549

◆ PseudoRegToInt()

unsigned long long int PseudoRegToInt ( char * str)

Converts pseudo register string to integer.

Parameters
str
Returns
unsigned long long int
2990{
2991 for (int i = 0; i < PSEUDO_REGISTER_MAP_LIST_LENGTH; i++)
2992 {
2993 if (!strcmp(str, PseudoRegisterMapList[i].Name))
2994 {
2995 return PseudoRegisterMapList[i].Type;
2996 }
2997 }
2998 return INVALID;
2999}
#define INVALID
Definition ScriptEngineCommonDefinitions.h:96
const SYMBOL_MAP PseudoRegisterMapList[]
Definition parse-table.c:1310
#define PSEUDO_REGISTER_MAP_LIST_LENGTH
Definition parse-table.h:13
long long unsigned Type
Definition ScriptEngineCommonDefinitions.h:31

◆ PushSymbol()

PSYMBOL_BUFFER PushSymbol ( PSYMBOL_BUFFER SymbolBuffer,
const PSYMBOL Symbol )

Gets a symbol and push it into the symbol buffer.

Parameters
SymbolBuffer
Symbol
Returns
PSYMBOL_BUFFER
2743{
2744 //
2745 // Calculate address to write new token
2746 //
2747 uintptr_t Head = (uintptr_t)SymbolBuffer->Head;
2748 uintptr_t Pointer = (uintptr_t)SymbolBuffer->Pointer;
2749 PSYMBOL WriteAddr = (PSYMBOL)(Head + Pointer * sizeof(SYMBOL));
2750
2751 if (Symbol->Type == SYMBOL_STRING_TYPE || Symbol->Type == SYMBOL_WSTRING_TYPE)
2752 {
2753 //
2754 // Update Pointer
2755 //
2756 SymbolBuffer->Pointer += GetSymbolHeapSize(Symbol);
2757
2758 //
2759 // Handle Overflow
2760 //
2761 if (SymbolBuffer->Pointer >= SymbolBuffer->Size - 1)
2762 {
2763 //
2764 // Calculate new size for the symbol B
2765 //
2766 unsigned int NewSize = SymbolBuffer->Size;
2767 do
2768 {
2769 NewSize *= 2;
2770 } while (NewSize <= SymbolBuffer->Pointer);
2771
2772 //
2773 // Allocate a new buffer for string list with doubled length
2774 //
2775 PSYMBOL NewHead = (PSYMBOL)malloc(NewSize * sizeof(SYMBOL));
2776
2777 if (NewHead == NULL)
2778 {
2779 printf("err, could not allocate buffer");
2780 return NULL;
2781 }
2782
2783 //
2784 // Copy old buffer to new buffer
2785 //
2786 memcpy(NewHead, SymbolBuffer->Head, SymbolBuffer->Size * sizeof(SYMBOL));
2787
2788 //
2789 // Free old buffer
2790 //
2791 free(SymbolBuffer->Head);
2792
2793 //
2794 // Update Head and size of SymbolBuffer
2795 //
2796 SymbolBuffer->Size = NewSize;
2797 SymbolBuffer->Head = NewHead;
2798 }
2799 WriteAddr = (PSYMBOL)((uintptr_t)SymbolBuffer->Head + (uintptr_t)Pointer * (uintptr_t)sizeof(SYMBOL));
2800 WriteAddr->Type = Symbol->Type;
2801 WriteAddr->Len = Symbol->Len;
2802 memcpy((char *)&WriteAddr->Value, (char *)&Symbol->Value, Symbol->Len);
2803 }
2804 else
2805 {
2806 //
2807 // Write input to the appropriate address in SymbolBuffer
2808 //
2809 *WriteAddr = *Symbol;
2810
2811 //
2812 // Update Pointer
2813 //
2814 SymbolBuffer->Pointer++;
2815
2816 //
2817 // Handle Overflow
2818 //
2819 if (Pointer >= SymbolBuffer->Size - 1)
2820 {
2821 //
2822 // Allocate a new buffer for string list with doubled length
2823 //
2824 PSYMBOL NewHead = (PSYMBOL)malloc(2 * SymbolBuffer->Size * sizeof(SYMBOL));
2825
2826 if (NewHead == NULL)
2827 {
2828 printf("err, could not allocate buffer");
2829 return NULL;
2830 }
2831
2832 //
2833 // Copy old Buffer to new buffer
2834 //
2835 memcpy(NewHead, SymbolBuffer->Head, SymbolBuffer->Size * sizeof(SYMBOL));
2836
2837 //
2838 // Free Old buffer
2839 //
2840 free(SymbolBuffer->Head);
2841
2842 //
2843 // Update Head and size of SymbolBuffer
2844 //
2845 SymbolBuffer->Size *= 2;
2846 SymbolBuffer->Head = NewHead;
2847 }
2848 }
2849
2850 return SymbolBuffer;
2851}

◆ RegisterToInt()

unsigned long long int RegisterToInt ( char * str)

Converts register string to integer.

Parameters
str
Returns
unsigned long long int
2889{
2890 //
2891 // Check for register names
2892 //
2893 for (int i = 0; i < REGISTER_MAP_LIST_LENGTH; i++)
2894 {
2895 if (!strcmp(str, RegisterMapList[i].Name))
2896 {
2897 return RegisterMapList[i].Type;
2898 }
2899 }
2900
2901 //
2902 // Check for hwdbg register names
2903 // Check if the registers start with '@hw_portX' or '@hw_pinX'
2904 //
2906 {
2907 const char * Ptr;
2908 UINT32 Num = 0;
2909
2910 //
2911 // Check for "hw_pin"
2912 //
2913 if (strncmp(str, "hw_pin", 6) == 0)
2914 {
2915 Ptr = str + 6;
2916 if (*Ptr == '\0')
2917 {
2918 return INVALID; // No number present
2919 }
2920 while (*Ptr)
2921 {
2922 if (!isdigit((unsigned char)*Ptr))
2923 {
2924 return INVALID; // Not a valid decimal number
2925 }
2926 Ptr++;
2927 }
2928 Num = atoi(str + 6);
2929
2930 //
2931 // port numbers start after the latest pin number
2932 //
2934 {
2935 return INVALID; // Invalid "hw_pinX"
2936 }
2937 else
2938 {
2939 return Num; // Valid "hw_pinX"
2940 }
2941 }
2942
2943 //
2944 // Check for "hw_port"
2945 //
2946 if (strncmp(str, "hw_port", 7) == 0)
2947 {
2948 Ptr = str + 7;
2949 if (*Ptr == '\0')
2950 {
2951 return INVALID; // No number present
2952 }
2953 while (*Ptr)
2954 {
2955 if (!isdigit((unsigned char)*Ptr))
2956 {
2957 return INVALID; // Not a valid decimal number
2958 }
2959
2960 Ptr++;
2961 }
2962
2963 Num = atoi(str + 7);
2964
2966 {
2967 return INVALID; // Invalid "hw_portX"
2968 }
2969 else
2970 {
2971 return Num + g_HwdbgInstanceInfo.numberOfPins; // Valid "hw_portX"
2972 }
2973 }
2974 }
2975
2976 //
2977 // Not a valid register name
2978 //
2979 return INVALID;
2980}
const SYMBOL_MAP RegisterMapList[]
Definition parse-table.c:1188
#define REGISTER_MAP_LIST_LENGTH
Definition parse-table.h:12
HWDBG_INSTANCE_INFORMATION g_HwdbgInstanceInfo
Instance information of the current hwdbg debuggee.
Definition globals.h:681
BOOLEAN g_HwdbgInstanceInfoIsValid
Shows whether the instance info is valid (received) or not.
Definition globals.h:687
UINT32 numberOfPorts
Definition HardwareDebugger.h:106
UINT32 numberOfPins
Definition HardwareDebugger.h:105

◆ RemoveSymbol()

void RemoveSymbol ( PSYMBOL * Symbol)

Frees the memory allocate by this Symbol.

Parameters
Symbol
2562{
2563 free(*Symbol);
2564 *Symbol = NULL;
2565 return;
2566}

◆ RemoveSymbolBuffer()

void RemoveSymbolBuffer ( PVOID SymbolBuffer)

Frees the memory allocated by SymbolBuffer.

Parameters
SymbolBuffer
2726{
2727 PSYMBOL_BUFFER SymBuf = (PSYMBOL_BUFFER)SymbolBuffer;
2728
2729 free(SymBuf->Message);
2730 free(SymBuf->Head);
2731 free(SymBuf);
2732}

◆ ScriptEngineBooleanExpresssionParse()

void ScriptEngineBooleanExpresssionParse ( UINT64 BooleanExpressionSize,
PTOKEN FirstToken,
PTOKEN_LIST MatchedStack,
PUSER_DEFINED_FUNCTION_NODE * UserDefinedFunctionHead,
PSYMBOL_BUFFER CodeBuffer,
char * str,
char * c,
PSCRIPT_ENGINE_ERROR_TYPE Error )

LALR parser used for parsing boolean expression.

Parameters
BooleanExpressionSize
FirstToken
MatchedStack
CodeBuffer
str
c
Error
2292{
2293 PTOKEN_LIST Stack = NewTokenList();
2294
2295 PTOKEN State = NewToken(STATE_ID, "0");
2296 Push(Stack, State);
2297
2298#ifdef _SCRIPT_ENGINE_LALR_DBG_EN
2299 printf("Boolean Expression: ");
2300 printf("%s", FirstToken->Value);
2301 for (int i = InputIdx - 1; i < BooleanExpressionSize; i++)
2302 {
2303 printf("%c", str[i]);
2304 }
2305 printf("\n\n");
2306#endif
2307
2308 //
2309 // End of File Token
2310 //
2311 PTOKEN EndToken = NewToken(END_OF_STACK, "$");
2312
2313 PTOKEN CurrentIn = CopyToken(FirstToken);
2314
2315 PTOKEN TopToken = NULL;
2316 PTOKEN Lhs = NULL;
2317 PTOKEN Temp = NULL;
2318 PTOKEN Operand = NULL;
2319 PTOKEN SemanticRule = NULL;
2320
2321 int Action = INVALID;
2322 int StateId = 0;
2323 int Goto = 0;
2324 int InputPointer = 0;
2325 int RhsSize = 0;
2326 unsigned int InputIdxTemp;
2327 char Ctemp;
2328
2329 while (1)
2330 {
2331 TopToken = Top(Stack);
2332 int TerminalId = LalrGetTerminalId(CurrentIn);
2333 StateId = (int)DecimalToSignedInt(TopToken->Value);
2334 if (StateId == INVALID || TerminalId < 0)
2335 {
2337 break;
2338 }
2339 Action = LalrActionTable[StateId][TerminalId];
2340
2341#ifdef _SCRIPT_ENGINE_LALR_DBG_EN
2342 printf("Stack :\n");
2343 PrintTokenList(Stack);
2344 printf("Action : %d\n\n", Action);
2345#endif
2346 if (Action == LALR_ACCEPT)
2347 {
2348 *Error = SCRIPT_ENGINE_ERROR_FREE;
2349 break;
2350 }
2351 if (Action == INVALID)
2352 {
2354 break;
2355 }
2356 if (Action == 0)
2357 {
2359 break;
2360 }
2361 else if (Action >= 0) // Shift
2362 {
2363 StateId = Action;
2364 Push(Stack, CurrentIn);
2365
2366 char buffer[20] = {0};
2367 sprintf(buffer, "%d", StateId);
2368 State = NewToken(STATE_ID, buffer);
2369 Push(Stack, State);
2370
2371 InputIdxTemp = InputIdx;
2372 Ctemp = *c;
2373
2374 CurrentIn = Scan(str, c);
2375 if (InputIdx - 1 > BooleanExpressionSize)
2376 {
2377 InputIdx = InputIdxTemp;
2378 *c = Ctemp;
2379
2380 RemoveToken(&CurrentIn);
2381
2382 CurrentIn = CopyToken(EndToken);
2383 }
2384 }
2385 else if (Action < 0) // Reduce
2386 {
2387 StateId = -Action;
2388 Lhs = (PTOKEN)&LalrLhs[StateId - 1];
2389 RhsSize = LalrGetRhsSize(StateId - 1);
2390 SemanticRule = (PTOKEN)&LalrSemanticRules[StateId - 1];
2391
2392 for (int i = 0; i < 2 * RhsSize; i++)
2393 {
2394 Temp = Pop(Stack);
2395 if (SemanticRule->Type == SEMANTIC_RULE && !strcmp(SemanticRule->Value, "@PUSH"))
2396 {
2397 if (LalrIsOperandType(Temp))
2398 {
2399 Operand = Temp;
2400 Push(MatchedStack, Operand);
2401 }
2402 else
2403 {
2404 RemoveToken(&Temp);
2405 }
2406 }
2407 else
2408 {
2409 RemoveToken(&Temp);
2410 }
2411 }
2412 if (SemanticRule->Type == SEMANTIC_RULE)
2413 {
2414 if (!strcmp(SemanticRule->Value, "@PUSH"))
2415 {
2416 }
2417 else
2418 {
2419 CodeGen(MatchedStack, UserDefinedFunctionHead, CodeBuffer, SemanticRule, Error);
2420 if (*Error != SCRIPT_ENGINE_ERROR_FREE)
2421 {
2422 break;
2423 }
2424 }
2425 }
2426
2427 Temp = Top(Stack);
2428 StateId = (int)DecimalToSignedInt(Temp->Value);
2429
2430 Goto = LalrGotoTable[StateId][LalrGetNonTerminalId(Lhs)];
2431
2432 PTOKEN LhsCopy = CopyToken(Lhs);
2433
2434 char buffer[20] = {0};
2435 sprintf(buffer, "%d", Goto);
2436 State = NewToken(STATE_ID, buffer);
2437 Push(Stack, LhsCopy);
2438 Push(Stack, State);
2439 }
2440 }
2441
2442 if (EndToken)
2443 RemoveToken(&EndToken);
2444
2445 if (Stack)
2446 RemoveTokenList(Stack);
2447
2448 if (CurrentIn)
2449 RemoveToken(&CurrentIn);
2450
2451 return;
2452}
#define LALR_ACCEPT
Definition ScriptEngineCommonDefinitions.h:97
const struct _TOKEN Lhs[RULES_COUNT]
Definition parse-table.c:2
const struct _TOKEN LalrLhs[RULES_COUNT]
Definition parse-table.c:1328
const unsigned int RhsSize[RULES_COUNT]
Definition parse-table.c:420
const int LalrGotoTable[LALR_STATE_COUNT][LALR_NONTERMINAL_COUNT]
Definition parse-table.c:1688
const int LalrActionTable[LALR_STATE_COUNT][LALR_TERMINAL_COUNT]
Definition parse-table.c:1933
const struct _TOKEN LalrSemanticRules[RULES_COUNT]
Definition parse-table.c:2178
PTOKEN Scan(char *str, char *c)
Perform scanning the script engine.
Definition scanner.c:875
int LalrGetTerminalId(PTOKEN Token)
Gets the Terminal Id object.
Definition common.c:1241
int LalrGetNonTerminalId(PTOKEN Token)
Gets the Non Terminal Id object.
Definition common.c:1224
unsigned long long DecimalToSignedInt(char *str)
Converts an decimal string to a signed integer.
Definition common.c:1414
struct _TOKEN * PTOKEN
@ END_OF_STACK
Definition common.h:55
@ STATE_ID
Definition common.h:43
int LalrGetRhsSize(int RuleId)
Returns the size of Right Hand Side (RHS) of a rule.
Definition script-engine.c:3243
void CodeGen(PTOKEN_LIST MatchedStack, PUSER_DEFINED_FUNCTION_NODE *UserDefinedFunctionHead, PSYMBOL_BUFFER CodeBuffer, PTOKEN Operator, PSCRIPT_ENGINE_ERROR_TYPE Error)
Script Engine code generator.
Definition script-engine.c:526
BOOL LalrIsOperandType(PTOKEN Token)
Returns TRUE if the Token can be the operand of an operator.
Definition script-engine.c:3264

◆ ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails()

BOOLEAN ScriptEngineConvertFileToPdbFileAndGuidAndAgeDetails ( const char * LocalFilePath,
char * PdbFilePath,
char * GuidAndAgeDetails,
BOOLEAN Is32BitModule )

Convert file to pdb attributes for symbols.

Parameters
LocalFilePath
PdbFilePath
GuidAndAgeDetails
Is32BitModule
Returns
BOOLEAN
253{
254 //
255 // A wrapper for pdb to path file and guid and age detail converter
256 //
258}
char * PdbFilePath
Definition HyperDbgScriptImports.h:63
char char BOOLEAN Is32BitModule
Definition HyperDbgScriptImports.h:63
char char * GuidAndAgeDetails
Definition HyperDbgScriptImports.h:63
BOOLEAN SymConvertFileToPdbFileAndGuidAndAgeDetails(const char *LocalFilePath, char *PdbFilePath, char *GuidAndAgeDetails, BOOLEAN Is32BitModule)
Convert a DLL to a Microsoft Symbol details like pdb file path and GUID.
Definition symbol-parser.cpp:1778

◆ ScriptEngineConvertFileToPdbPath()

BOOLEAN ScriptEngineConvertFileToPdbPath ( const char * LocalFilePath,
char * ResultPath )

Convert local file to pdb path.

Parameters
LocalFilePath
ResultPath
Returns
BOOLEAN
174{
175 //
176 // A wrapper for pdb to path converter
177 //
178 return SymConvertFileToPdbPath(LocalFilePath, ResultPath);
179}
char * ResultPath
Definition HyperDbgScriptImports.h:61
BOOLEAN SymConvertFileToPdbPath(const char *LocalFilePath, char *ResultPath)
Convert a DLL to a Microsoft Symbol path.
Definition symbol-parser.cpp:1687

◆ ScriptEngineConvertNameToAddress()

UINT64 ScriptEngineConvertNameToAddress ( const char * FunctionOrVariableName,
PBOOLEAN WasFound )

Converts name to address.

Parameters
FunctionOrVariableName
WasFound
Returns
UINT64
34{
35 //
36 // A wrapper for pdb parser
37 //
38 return SymConvertNameToAddress(FunctionOrVariableName, WasFound);
39}
PBOOLEAN WasFound
Definition HyperDbgScriptImports.h:45
UINT64 SymConvertNameToAddress(const char *FunctionOrVariableName, PBOOLEAN WasFound)
Convert function name to address.
Definition symbol-parser.cpp:804

◆ ScriptEngineCreateSymbolTableForDisassembler()

BOOLEAN ScriptEngineCreateSymbolTableForDisassembler ( void * CallbackFunction)

Create symbol table for disassembler.

Parameters
CallbackFunction
Returns
BOOLEAN
158{
159 //
160 // A wrapper for pdb symbol table callback creator
161 //
162 return SymCreateSymbolTableForDisassembler(CallbackFunction);
163}
BOOLEAN SymCreateSymbolTableForDisassembler(void *CallbackFunction)
Create symbol table for disassembler.
Definition symbol-parser.cpp:1147

◆ ScriptEngineGetDataTypeSize()

BOOLEAN ScriptEngineGetDataTypeSize ( CHAR * TypeName,
UINT64 * TypeSize )

Get size of a data type (structure)

Parameters
TypeName
TypeSize
Returns
BOOLEAN
143{
144 //
145 // A wrapper for getting size of the structure
146 //
147 return SymGetDataTypeSize(TypeName, TypeSize);
148}
UINT64 * TypeSize
Definition HyperDbgScriptImports.h:57
BOOLEAN SymGetDataTypeSize(CHAR *TypeName, UINT64 *TypeSize)
Get the size of structures from the symbols.
Definition symbol-parser.cpp:1031

◆ ScriptEngineGetFieldOffset()

BOOLEAN ScriptEngineGetFieldOffset ( CHAR * TypeName,
CHAR * FieldName,
UINT32 * FieldOffset )

Get offset of a field from the structure.

Parameters
TypeName
FieldName
FieldOffset
Returns
BOOLEAN
127{
128 //
129 // A wrapper for search for fields in the structure
130 //
131 return SymGetFieldOffset(TypeName, FieldName, FieldOffset);
132}
CHAR * FieldName
Definition HyperDbgScriptImports.h:55
CHAR UINT32 * FieldOffset
Definition HyperDbgScriptImports.h:55
BOOLEAN SymGetFieldOffset(CHAR *TypeName, CHAR *FieldName, UINT32 *FieldOffset)
Search and show symbols.
Definition symbol-parser.cpp:942

◆ ScriptEngineLoadFileSymbol()

UINT32 ScriptEngineLoadFileSymbol ( UINT64 BaseAddress,
const char * PdbFileName,
const char * CustomModuleName )

Load symbol files

Parameters
BaseAddress
PdbFileName
CustomModuleName
Returns
UINT32
54{
55 //
56 // A wrapper for pdb parser
57 //
59}
const char const char * CustomModuleName
Definition HyperDbgScriptImports.h:47
const char * PdbFileName
Definition HyperDbgScriptImports.h:47
UINT32 SymLoadFileSymbol(UINT64 BaseAddress, const char *PdbFileName, const char *CustomModuleName)
load symbol based on a file name and GUID
Definition symbol-parser.cpp:532

◆ ScriptEngineParse()

PVOID ScriptEngineParse ( char * str)

The entry point of script engine.

Parameters
str
Returns
PVOID
268{
269 PTOKEN_LIST Stack = NewTokenList();
270
271 PTOKEN_LIST MatchedStack = NewTokenList();
272 PSYMBOL_BUFFER CodeBuffer = NewSymbolBuffer();
273
274 PUSER_DEFINED_FUNCTION_NODE UserDefinedFunctionHead = NULL;
275
277 char * ErrorMessage = NULL;
278
279 static FirstCall = 1;
280 if (FirstCall)
281 {
284 FirstCall = 0;
285 }
286
287 PTOKEN TopToken = NewUnknownToken();
288
289 int NonTerminalId;
290 int TerminalId;
291 int RuleId;
292 char c;
293 BOOL WaitForWaitStatementBooleanExpression = FALSE;
294
295 //
296 // Initialize Scanner
297 //
298 InputIdx = 0;
299 CurrentLine = 0;
300 CurrentLineIdx = 0;
301
302 //
303 // End of File Token
304 //
305 PTOKEN EndToken = NewToken(END_OF_STACK, "$");
306
307 //
308 // Start Token
309 //
311
312 Push(Stack, EndToken);
313 Push(Stack, StartToken);
314
315 c = sgetc(str);
316
317 PTOKEN CurrentIn = Scan(str, &c);
318 if (CurrentIn->Type == UNKNOWN)
319 {
321 ErrorMessage = HandleError(&Error, str);
322 CodeBuffer->Message = ErrorMessage;
323
324 RemoveTokenList(Stack);
325 RemoveTokenList(MatchedStack);
326 RemoveToken(&CurrentIn);
327 return (PVOID)CodeBuffer;
328 }
329
330 do
331 {
332 RemoveToken(&TopToken);
333 TopToken = Pop(Stack);
334
335#ifdef _SCRIPT_ENGINE_LL1_DBG_EN
336 printf("\nTop Token :\n");
337 PrintToken(TopToken);
338 printf("\nCurrent Input :\n");
339 PrintToken(CurrentIn);
340 printf("\n");
341#endif
342
343 if (TopToken->Type == NON_TERMINAL)
344 {
345 if (!strcmp(TopToken->Value, "BOOLEAN_EXPRESSION"))
346 {
347 UINT64 BooleanExpressionSize = BooleanExpressionExtractEnd(str, &WaitForWaitStatementBooleanExpression, CurrentIn);
348
349 ScriptEngineBooleanExpresssionParse(BooleanExpressionSize, CurrentIn, MatchedStack, &UserDefinedFunctionHead, CodeBuffer, str, &c, &Error);
350 if (Error != SCRIPT_ENGINE_ERROR_FREE)
351 {
352 break;
353 }
354
355 RemoveToken(&CurrentIn);
356 CurrentIn = Scan(str, &c);
357 if (CurrentIn->Type == UNKNOWN)
358 {
360 break;
361 }
362
363 RemoveToken(&CurrentIn);
364 CurrentIn = Scan(str, &c);
365 if (CurrentIn->Type == UNKNOWN)
366 {
368 break;
369 }
370 RemoveToken(&TopToken);
371 TopToken = Pop(Stack);
372 }
373 else
374 {
375 NonTerminalId = GetNonTerminalId(TopToken);
376 if (NonTerminalId == INVALID)
377 {
379 break;
380 }
381
382 TerminalId = GetTerminalId(CurrentIn);
383 if (TerminalId == INVALID)
384 {
386 break;
387 }
388
389 RuleId = ParseTable[NonTerminalId][TerminalId];
390 if (RuleId == INVALID)
391 {
393 break;
394 }
395
396 //
397 // Push RHS Reversely into stack
398 //
399 for (int i = RhsSize[RuleId] - 1; i >= 0; i--)
400 {
401 PTOKEN Token = (PTOKEN)&Rhs[RuleId][i];
402
403 if (Token->Type == EPSILON)
404 break;
405
406 PTOKEN DuplicatedToken = CopyToken(Token);
407 Push(Stack, DuplicatedToken);
408 }
409 }
410 }
411 else if (TopToken->Type == SEMANTIC_RULE)
412 {
413 if (!strcmp(TopToken->Value, "@PUSH"))
414 {
415 RemoveToken(&TopToken);
416 TopToken = Pop(Stack);
417
418 Push(MatchedStack, CurrentIn);
419
420 CurrentIn = Scan(str, &c);
421 if (CurrentIn->Type == UNKNOWN)
422 {
424 break;
425 }
426 }
427
428 else
429 {
430 if (!strcmp(TopToken->Value, "@START_OF_FOR"))
431 {
432 WaitForWaitStatementBooleanExpression = TRUE;
433 }
434 CodeGen(MatchedStack, &UserDefinedFunctionHead, CodeBuffer, TopToken, &Error);
435 if (Error != SCRIPT_ENGINE_ERROR_FREE)
436 {
437 break;
438 }
439 }
440 }
441 else
442 {
443 if (!IsEqual(TopToken, CurrentIn))
444 {
446 break;
447 }
448 else
449 {
450 RemoveToken(&CurrentIn);
451 CurrentIn = Scan(str, &c);
452
453 if (CurrentIn->Type == UNKNOWN)
454 {
456 break;
457 }
458 }
459 }
460#ifdef _SCRIPT_ENGINE_LL1_DBG_EN
461 printf("Stack: \n");
462 PrintTokenList(Stack);
463 printf("\n");
464#endif
465 } while (TopToken->Type != END_OF_STACK);
466
467 if (Error != SCRIPT_ENGINE_ERROR_FREE)
468 {
469 ErrorMessage = HandleError(&Error, str);
471 }
472 else
473 {
474 ErrorMessage = NULL;
475 }
476 CodeBuffer->Message = ErrorMessage;
477
478 if (Stack)
479 RemoveTokenList(Stack);
480
481 if (MatchedStack)
482 RemoveTokenList(MatchedStack);
483
484 if (UserDefinedFunctionHead)
485 {
486 PUSER_DEFINED_FUNCTION_NODE Node = UserDefinedFunctionHead;
487 while (Node)
488 {
489 if (Node->Name)
490 free(Node->Name);
491
492 if (Node->ParameterBuffer)
494
495 PUSER_DEFINED_FUNCTION_NODE Temp = Node;
496 Node = Node->NextNode;
497 free(Temp);
498 }
499 UserDefinedFunctionHead = NULL;
500 }
501
502 if (CurrentIn)
503 RemoveToken(&CurrentIn);
504
505 if (TopToken)
506 RemoveToken(&TopToken);
507
509 {
512 }
513
514 return (PVOID)CodeBuffer;
515}
const struct _TOKEN Rhs[RULES_COUNT][MAX_RHS_LEN]
Definition parse-table.c:211
const int ParseTable[NONETERMINAL_COUNT][TERMINAL_COUNT]
Definition parse-table.c:787
#define START_VARIABLE
Definition parse-table.h:7
char sgetc(char *str)
returns last character of string
Definition scanner.c:941
char IsEqual(const PTOKEN Token1, const PTOKEN Token2)
Checks whether the value and type of Token1 and Token2 are the same.
Definition common.c:1337
PTOKEN NewUnknownToken()
Allocates a new token.
Definition common.c:20
void CleanTempList(void)
Resets the temporary variables map.
Definition common.c:709
int GetNonTerminalId(PTOKEN Token)
Gets the Non Terminal Id object.
Definition common.c:1112
int GetTerminalId(PTOKEN Token)
Gets the Terminal Id object.
Definition common.c:1129
@ UNKNOWN
Definition common.h:65
@ NON_TERMINAL
Definition common.h:53
enum _SCRIPT_ENGINE_ERROR_TYPE SCRIPT_ENGINE_ERROR_TYPE
UINT64 BooleanExpressionExtractEnd(char *str, BOOL *WaitForWaitStatementBooleanExpression, PTOKEN CurrentIn)
Computes the boolean expression length starting from the current input position.
Definition script-engine.c:2232
char * HandleError(PSCRIPT_ENGINE_ERROR_TYPE Error, char *str)
Prints some information about the error.
Definition script-engine.c:3028
void ScriptEngineBooleanExpresssionParse(UINT64 BooleanExpressionSize, PTOKEN FirstToken, PTOKEN_LIST MatchedStack, PUSER_DEFINED_FUNCTION_NODE *UserDefinedFunctionHead, PSYMBOL_BUFFER CodeBuffer, char *str, char *c, PSCRIPT_ENGINE_ERROR_TYPE Error)
LALR parser used for parsing boolean expression.
Definition script-engine.c:2283

◆ ScriptEngineSearchSymbolForMask()

UINT32 ScriptEngineSearchSymbolForMask ( const char * SearchMask)

Search for a special mask.

Parameters
SearchMask
Returns
UINT32
110{
111 //
112 // A wrapper for pdb mask searcher
113 //
114 return SymSearchSymbolForMask(SearchMask);
115}
UINT32 SymSearchSymbolForMask(const char *SearchMask)
Gets the offset from the symbol.
Definition symbol-parser.cpp:1100

◆ ScriptEngineSetHwdbgInstanceInfo()

BOOLEAN ScriptEngineSetHwdbgInstanceInfo ( HWDBG_INSTANCE_INFORMATION * InstancInfo)

Set hwdbg instance info for the script engine.

Parameters
InstancInfo
Returns
BOOLEAN
3333{
3334 //
3335 // Copy the instance info into the global variable
3336 //
3337 memcpy(&g_HwdbgInstanceInfo, InstancInfo, sizeof(HWDBG_INSTANCE_INFORMATION));
3338
3339 //
3340 // Indicate that the instance info is valid
3341 //
3343
3344 return TRUE;
3345}
The structure of script capabilities information in hwdbg.
Definition HardwareDebugger.h:91

◆ ScriptEngineSetTextMessageCallback()

VOID ScriptEngineSetTextMessageCallback ( PVOID Handler)

Set the message handler as an alternative to printf.

Parameters
Handler
Returns
VOID
69{
71}
void SymSetTextMessageCallback(PVOID Handler)
Set the function callback that will be called if any message needs to be shown.
Definition symbol-parser.cpp:32

◆ ScriptEngineShowDataBasedOnSymbolTypes()

BOOLEAN ScriptEngineShowDataBasedOnSymbolTypes ( const char * TypeName,
UINT64 Address,
BOOLEAN IsStruct,
PVOID BufferAddress,
const char * AdditionalParameters )

Show data based on symbol types.

Parameters
TypeName
Address
IsStruct
BufferAddress
AdditionalParameters
Returns
BOOLEAN
220{
221 //
222 // A wrapper for showing types and data within structures
223 //
225}
UINT64 BOOLEAN IsStruct
Definition HyperDbgScriptImports.h:67
UINT64 Address
Definition HyperDbgScriptImports.h:67
UINT64 BOOLEAN PVOID const char * AdditionalParameters
Definition HyperDbgScriptImports.h:67
UINT64 BOOLEAN PVOID BufferAddress
Definition HyperDbgScriptImports.h:67
BOOLEAN SymShowDataBasedOnSymbolTypes(const char *TypeName, UINT64 Address, BOOLEAN IsStruct, PVOID BufferAddress, const char *AdditionalParameters)
Perform task for showing structures and data.
Definition symbol-parser.cpp:2141

◆ ScriptEngineSymbolAbortLoading()

VOID ScriptEngineSymbolAbortLoading ( )

Cancel loading.

Returns
VOID
234{
235 //
236 // A wrapper for aborting download and reload
237 //
239}
VOID SymbolAbortLoading()
In the case of pressing CTRL+C, it sets a flag to abort the execution of the 'reload'ing and the 'dow...
Definition symbol-parser.cpp:2119

◆ ScriptEngineSymbolInitLoad()

BOOLEAN ScriptEngineSymbolInitLoad ( PVOID BufferToStoreDetails,
UINT32 StoredLength,
BOOLEAN DownloadIfAvailable,
const char * SymbolPath,
BOOLEAN IsSilentLoad )

Initial load of the symbols.

Parameters
BufferToStoreDetails
StoredLength
DownloadIfAvailable
SymbolPath
IsSilentLoad
Returns
BOOLEAN
197{
198 //
199 // A wrapper for pdb and modules parser
200 //
202}
UINT32 BOOLEAN const char * SymbolPath
Definition HyperDbgScriptImports.h:65
UINT32 BOOLEAN const char BOOLEAN IsSilentLoad
Definition HyperDbgScriptImports.h:65
UINT32 StoredLength
Definition HyperDbgScriptImports.h:65
UINT32 BOOLEAN DownloadIfAvailable
Definition HyperDbgScriptImports.h:65
BOOLEAN SymbolInitLoad(PVOID BufferToStoreDetails, UINT32 StoredLength, BOOLEAN DownloadIfAvailable, const char *SymbolPath, BOOLEAN IsSilentLoad)
check if the pdb files of loaded symbols are available or not
Definition symbol-parser.cpp:1851

◆ ScriptEngineUnloadAllSymbols()

UINT32 ScriptEngineUnloadAllSymbols ( )

Unload all the previously loaded symbols.

Returns
UINT32
80{
81 //
82 // A wrapper for pdb unloader
83 //
84 return SymUnloadAllSymbols();
85}
UINT32 SymUnloadAllSymbols()
Unload all the symbols.
Definition symbol-parser.cpp:726

◆ ScriptEngineUnloadModuleSymbol()

UINT32 ScriptEngineUnloadModuleSymbol ( char * ModuleName)

Unload a special pdb.

Parameters
ModuleName
Returns
UINT32
95{
96 //
97 // A wrapper for pdb unloader
98 //
99 return SymUnloadModuleSymbol(ModuleName);
100}
UINT32 SymUnloadModuleSymbol(char *ModuleName)
Unload one module symbol.
Definition symbol-parser.cpp:667

◆ SemanticRuleToInt()

unsigned long long int SemanticRuleToInt ( char * str)

Converts a sematinc rule token to integer.

Parameters
str
Returns
unsigned long long int
3009{
3010 for (int i = 0; i < SEMANTIC_RULES_MAP_LIST_LENGTH; i++)
3011 {
3012 if (!strcmp(str, SemanticRulesMapList[i].Name))
3013 {
3014 return SemanticRulesMapList[i].Type;
3015 }
3016 }
3017 return INVALID;
3018}
const SYMBOL_MAP SemanticRulesMapList[]
Definition parse-table.c:1050
#define SEMANTIC_RULES_MAP_LIST_LENGTH
Definition parse-table.h:14

◆ ToSymbol()

PSYMBOL ToSymbol ( PTOKEN Token,
PSCRIPT_ENGINE_ERROR_TYPE Error )

Converts Token to Symbol and returns the reference to it.

Parameters
Token
Error
Returns
PSYMBOL
2613{
2614 PSYMBOL Symbol = NewSymbol();
2615 switch (Token->Type)
2616 {
2617 case GLOBAL_ID:
2618 Symbol->Value = GetGlobalIdentifierVal(Token);
2620 return Symbol;
2621
2622 case LOCAL_ID:
2623 Symbol->Value = GetLocalIdentifierVal(Token);
2625 return Symbol;
2626
2627 case DECIMAL:
2628 Symbol->Value = DecimalToInt(Token->Value);
2629 SetType(&Symbol->Type, SYMBOL_NUM_TYPE);
2630 return Symbol;
2631
2632 case HEX:
2633 Symbol->Value = HexToInt(Token->Value);
2634 SetType(&Symbol->Type, SYMBOL_NUM_TYPE);
2635 return Symbol;
2636
2637 case OCTAL:
2638 Symbol->Value = OctalToInt(Token->Value);
2639 SetType(&Symbol->Type, SYMBOL_NUM_TYPE);
2640 return Symbol;
2641
2642 case BINARY:
2643 Symbol->Value = BinaryToInt(Token->Value);
2644 SetType(&Symbol->Type, SYMBOL_NUM_TYPE);
2645 return Symbol;
2646
2647 case REGISTER:
2648 Symbol->Value = RegisterToInt(Token->Value);
2650 return Symbol;
2651
2652 case PSEUDO_REGISTER:
2653 Symbol->Value = PseudoRegToInt(Token->Value);
2655 return Symbol;
2656
2657 case SEMANTIC_RULE:
2658 Symbol->Value = SemanticRuleToInt(Token->Value);
2660 return Symbol;
2661
2662 case TEMP:
2663 Symbol->Value = DecimalToInt(Token->Value);
2664 SetType(&Symbol->Type, SYMBOL_TEMP_TYPE);
2665 return Symbol;
2666
2667 case STACK_TEMP:
2668 Symbol->Value = DecimalToInt(Token->Value);
2670 return Symbol;
2671
2672 case STRING:
2673 RemoveSymbol(&Symbol);
2674 return NewStringSymbol(Token);
2675
2676 case WSTRING:
2677 RemoveSymbol(&Symbol);
2678 return NewWstringSymbol(Token);
2679
2681 Symbol->Value = GetFunctionParameterIdentifier(Token);
2683 return Symbol;
2684
2685 default:
2687 Symbol->Type = INVALID;
2688 Symbol->Value = INVALID;
2689 return Symbol;
2690 }
2691}
#define SYMBOL_REGISTER_TYPE
Definition ScriptEngineCommonDefinitions.h:57
#define SYMBOL_TEMP_TYPE
Definition ScriptEngineCommonDefinitions.h:60
#define SYMBOL_PSEUDO_REG_TYPE
Definition ScriptEngineCommonDefinitions.h:58
unsigned long long OctalToInt(char *str)
Converts an octal string to integer.
Definition common.c:1481
unsigned long long BinaryToInt(char *str)
Converts a binary string to integer.
Definition common.c:1503
unsigned long long HexToInt(char *str)
Converts an hexadecimal string to integer.
Definition common.c:1448
@ STACK_TEMP
Definition common.h:64
int GetFunctionParameterIdentifier(PTOKEN Token)
Definition script-engine.c:3222
PSYMBOL NewWstringSymbol(PTOKEN Token)
Allocates a new SYMBOL with wstring type and returns the reference to it.
Definition script-engine.c:2515
unsigned long long int RegisterToInt(char *str)
Converts register string to integer.
Definition script-engine.c:2888
int GetGlobalIdentifierVal(PTOKEN Token)
Returns the integer assigned to global variable.
Definition script-engine.c:3138
unsigned long long int SemanticRuleToInt(char *str)
Converts a sematinc rule token to integer.
Definition script-engine.c:3008
int GetLocalIdentifierVal(PTOKEN Token)
Returns the integer assigned to local variable.
Definition script-engine.c:3159
unsigned long long int PseudoRegToInt(char *str)
Converts pseudo register string to integer.
Definition script-engine.c:2989
PSYMBOL NewStringSymbol(PTOKEN Token)
Allocates a new SYMBOL with string type and returns the reference to it.
Definition script-engine.c:2487

Variable Documentation

◆ g_HwdbgInstanceInfo

HWDBG_INSTANCE_INFORMATION g_HwdbgInstanceInfo
extern

Instance information of the current hwdbg debuggee.

◆ g_HwdbgInstanceInfoIsValid

BOOLEAN g_HwdbgInstanceInfoIsValid
extern

Shows whether the instance info is valid (received) or not.