Browse code

imphash: add parsing of import table and calculate imphash

Kevin Lin authored on 2016/06/22 06:17:40
Showing 1 changed files
... ...
@@ -208,6 +208,43 @@ struct offset_list {
208 208
     struct offset_list *next;
209 209
 };
210 210
 
211
+struct pe_image_import_descriptor {
212
+    union {
213
+        uint32_t Characteristics;
214
+        uint32_t OriginalFirstThunk;
215
+    } u;
216
+    uint32_t TimeDateStamp;
217
+    uint32_t ForwarderChain;
218
+    uint32_t Name;
219
+    uint32_t FirstThunk;
220
+};
221
+
222
+#define IMAGE_ORDINAL_FLAG32  0x80000000
223
+#define IMAGE_ORDINAL_FLAG64  0x8000000000000000L
224
+
225
+struct pe_image_thunk32 {
226
+    union {
227
+        uint32_t ForwarderString;
228
+        uint32_t Function;
229
+        uint32_t Ordinal;
230
+        uint32_t AddressOfData;
231
+    } u;
232
+};
233
+
234
+struct pe_image_thunk64 {
235
+    union {
236
+        uint64_t ForwarderString;
237
+        uint64_t Function;
238
+        uint64_t Ordinal;
239
+        uint64_t AddressOfData;
240
+    } u;
241
+};
242
+
243
+struct pe_image_import_by_name {
244
+    uint16_t Hint;
245
+    uint8_t Name[1];
246
+};
247
+
211 248
 static void cli_multifree(void *f, ...) {
212 249
     void *ff;
213 250
     va_list ap;
... ...
@@ -554,6 +591,1838 @@ end:
554 554
     return ret;
555 555
 }
556 556
 
557
+/* imptbl scanning */
558
+static char *pe_ordinal(char *dll, uint16_t ord)
559
+{
560
+  char name[64];
561
+  name[0] = '\0';
562
+
563
+  if (strncasecmp(dll, "WS2_32.dll", 10) == 0 ||
564
+      strncasecmp(dll, "wsock32.dll", 11) == 0)
565
+  {
566
+    switch(ord) {
567
+      case 1:
568
+        sprintf(name, "accept");
569
+        break;
570
+      case 2:
571
+        sprintf(name, "bind");
572
+        break;
573
+      case 3:
574
+        sprintf(name, "closesocket");
575
+        break;
576
+      case 4:
577
+        sprintf(name, "connect");
578
+        break;
579
+      case 5:
580
+        sprintf(name, "getpeername");
581
+        break;
582
+      case 6:
583
+        sprintf(name, "getsockname");
584
+        break;
585
+      case 7:
586
+        sprintf(name, "getsockopt");
587
+        break;
588
+      case 8:
589
+        sprintf(name, "htonl");
590
+        break;
591
+      case 9:
592
+        sprintf(name, "htons");
593
+        break;
594
+      case 10:
595
+        sprintf(name, "ioctlsocket");
596
+        break;
597
+      case 11:
598
+        sprintf(name, "inet_addr");
599
+        break;
600
+      case 12:
601
+        sprintf(name, "inet_ntoa");
602
+        break;
603
+      case 13:
604
+        sprintf(name, "listen");
605
+        break;
606
+      case 14:
607
+        sprintf(name, "ntohl");
608
+        break;
609
+      case 15:
610
+        sprintf(name, "ntohs");
611
+        break;
612
+      case 16:
613
+        sprintf(name, "recv");
614
+        break;
615
+      case 17:
616
+        sprintf(name, "recvfrom");
617
+        break;
618
+      case 18:
619
+        sprintf(name, "select");
620
+        break;
621
+      case 19:
622
+        sprintf(name, "send");
623
+        break;
624
+      case 20:
625
+        sprintf(name, "sendto");
626
+        break;
627
+      case 21:
628
+        sprintf(name, "setsockopt");
629
+        break;
630
+      case 22:
631
+        sprintf(name, "shutdown");
632
+        break;
633
+      case 23:
634
+        sprintf(name, "socket");
635
+        break;
636
+      case 24:
637
+        sprintf(name, "GetAddrInfoW");
638
+        break;
639
+      case 25:
640
+        sprintf(name, "GetNameInfoW");
641
+        break;
642
+      case 26:
643
+        sprintf(name, "WSApSetPostRoutine");
644
+        break;
645
+      case 27:
646
+        sprintf(name, "FreeAddrInfoW");
647
+        break;
648
+      case 28:
649
+        sprintf(name, "WPUCompleteOverlappedRequest");
650
+        break;
651
+      case 29:
652
+        sprintf(name, "WSAAccept");
653
+        break;
654
+      case 30:
655
+        sprintf(name, "WSAAddressToStringA");
656
+        break;
657
+      case 31:
658
+        sprintf(name, "WSAAddressToStringW");
659
+        break;
660
+      case 32:
661
+        sprintf(name, "WSACloseEvent");
662
+        break;
663
+      case 33:
664
+        sprintf(name, "WSAConnect");
665
+        break;
666
+      case 34:
667
+        sprintf(name, "WSACreateEvent");
668
+        break;
669
+      case 35:
670
+        sprintf(name, "WSADuplicateSocketA");
671
+        break;
672
+      case 36:
673
+        sprintf(name, "WSADuplicateSocketW");
674
+        break;
675
+      case 37:
676
+        sprintf(name, "WSAEnumNameSpaceProvidersA");
677
+        break;
678
+      case 38:
679
+        sprintf(name, "WSAEnumNameSpaceProvidersW");
680
+        break;
681
+      case 39:
682
+        sprintf(name, "WSAEnumNetworkEvents");
683
+        break;
684
+      case 40:
685
+        sprintf(name, "WSAEnumProtocolsA");
686
+        break;
687
+      case 41:
688
+        sprintf(name, "WSAEnumProtocolsW");
689
+        break;
690
+      case 42:
691
+        sprintf(name, "WSAEventSelect");
692
+        break;
693
+      case 43:
694
+        sprintf(name, "WSAGetOverlappedResult");
695
+        break;
696
+      case 44:
697
+        sprintf(name, "WSAGetQOSByName");
698
+        break;
699
+      case 45:
700
+        sprintf(name, "WSAGetServiceClassInfoA");
701
+        break;
702
+      case 46:
703
+        sprintf(name, "WSAGetServiceClassInfoW");
704
+        break;
705
+      case 47:
706
+        sprintf(name, "WSAGetServiceClassNameByClassIdA");
707
+        break;
708
+      case 48:
709
+        sprintf(name, "WSAGetServiceClassNameByClassIdW");
710
+        break;
711
+      case 49:
712
+        sprintf(name, "WSAHtonl");
713
+        break;
714
+      case 50:
715
+        sprintf(name, "WSAHtons");
716
+        break;
717
+      case 51:
718
+        sprintf(name, "gethostbyaddr");
719
+        break;
720
+      case 52:
721
+        sprintf(name, "gethostbyname");
722
+        break;
723
+      case 53:
724
+        sprintf(name, "getprotobyname");
725
+        break;
726
+      case 54:
727
+        sprintf(name, "getprotobynumber");
728
+        break;
729
+      case 55:
730
+        sprintf(name, "getservbyname");
731
+        break;
732
+      case 56:
733
+        sprintf(name, "getservbyport");
734
+        break;
735
+      case 57:
736
+        sprintf(name, "gethostname");
737
+        break;
738
+      case 58:
739
+        sprintf(name, "WSAInstallServiceClassA");
740
+        break;
741
+      case 59:
742
+        sprintf(name, "WSAInstallServiceClassW");
743
+        break;
744
+      case 60:
745
+        sprintf(name, "WSAIoctl");
746
+        break;
747
+      case 61:
748
+        sprintf(name, "WSAJoinLeaf");
749
+        break;
750
+      case 62:
751
+        sprintf(name, "WSALookupServiceBeginA");
752
+        break;
753
+      case 63:
754
+        sprintf(name, "WSALookupServiceBeginW");
755
+        break;
756
+      case 64:
757
+        sprintf(name, "WSALookupServiceEnd");
758
+        break;
759
+      case 65:
760
+        sprintf(name, "WSALookupServiceNextA");
761
+        break;
762
+      case 66:
763
+        sprintf(name, "WSALookupServiceNextW");
764
+        break;
765
+      case 67:
766
+        sprintf(name, "WSANSPIoctl");
767
+        break;
768
+      case 68:
769
+        sprintf(name, "WSANtohl");
770
+        break;
771
+      case 69:
772
+        sprintf(name, "WSANtohs");
773
+        break;
774
+      case 70:
775
+        sprintf(name, "WSAProviderConfigChange");
776
+        break;
777
+      case 71:
778
+        sprintf(name, "WSARecv");
779
+        break;
780
+      case 72:
781
+        sprintf(name, "WSARecvDisconnect");
782
+        break;
783
+      case 73:
784
+        sprintf(name, "WSARecvFrom");
785
+        break;
786
+      case 74:
787
+        sprintf(name, "WSARemoveServiceClass");
788
+        break;
789
+      case 75:
790
+        sprintf(name, "WSAResetEvent");
791
+        break;
792
+      case 76:
793
+        sprintf(name, "WSASend");
794
+        break;
795
+      case 77:
796
+        sprintf(name, "WSASendDisconnect");
797
+        break;
798
+      case 78:
799
+        sprintf(name, "WSASendTo");
800
+        break;
801
+      case 79:
802
+        sprintf(name, "WSASetEvent");
803
+        break;
804
+      case 80:
805
+        sprintf(name, "WSASetServiceA");
806
+        break;
807
+      case 81:
808
+        sprintf(name, "WSASetServiceW");
809
+        break;
810
+      case 82:
811
+        sprintf(name, "WSASocketA");
812
+        break;
813
+      case 83:
814
+        sprintf(name, "WSASocketW");
815
+        break;
816
+      case 84:
817
+        sprintf(name, "WSAStringToAddressA");
818
+        break;
819
+      case 85:
820
+        sprintf(name, "WSAStringToAddressW");
821
+        break;
822
+      case 86:
823
+        sprintf(name, "WSAWaitForMultipleEvents");
824
+        break;
825
+      case 87:
826
+        sprintf(name, "WSCDeinstallProvider");
827
+        break;
828
+      case 88:
829
+        sprintf(name, "WSCEnableNSProvider");
830
+        break;
831
+      case 89:
832
+        sprintf(name, "WSCEnumProtocols");
833
+        break;
834
+      case 90:
835
+        sprintf(name, "WSCGetProviderPath");
836
+        break;
837
+      case 91:
838
+        sprintf(name, "WSCInstallNameSpace");
839
+        break;
840
+      case 92:
841
+        sprintf(name, "WSCInstallProvider");
842
+        break;
843
+      case 93:
844
+        sprintf(name, "WSCUnInstallNameSpace");
845
+        break;
846
+      case 94:
847
+        sprintf(name, "WSCUpdateProvider");
848
+        break;
849
+      case 95:
850
+        sprintf(name, "WSCWriteNameSpaceOrder");
851
+        break;
852
+      case 96:
853
+        sprintf(name, "WSCWriteProviderOrder");
854
+        break;
855
+      case 97:
856
+        sprintf(name, "freeaddrinfo");
857
+        break;
858
+      case 98:
859
+        sprintf(name, "getaddrinfo");
860
+        break;
861
+      case 99:
862
+        sprintf(name, "getnameinfo");
863
+        break;
864
+      case 101:
865
+        sprintf(name, "WSAAsyncSelect");
866
+        break;
867
+      case 102:
868
+        sprintf(name, "WSAAsyncGetHostByAddr");
869
+        break;
870
+      case 103:
871
+        sprintf(name, "WSAAsyncGetHostByName");
872
+        break;
873
+      case 104:
874
+        sprintf(name, "WSAAsyncGetProtoByNumber");
875
+        break;
876
+      case 105:
877
+        sprintf(name, "WSAAsyncGetProtoByName");
878
+        break;
879
+      case 106:
880
+        sprintf(name, "WSAAsyncGetServByPort");
881
+        break;
882
+      case 107:
883
+        sprintf(name, "WSAAsyncGetServByName");
884
+        break;
885
+      case 108:
886
+        sprintf(name, "WSACancelAsyncRequest");
887
+        break;
888
+      case 109:
889
+        sprintf(name, "WSASetBlockingHook");
890
+        break;
891
+      case 110:
892
+        sprintf(name, "WSAUnhookBlockingHook");
893
+        break;
894
+      case 111:
895
+        sprintf(name, "WSAGetLastError");
896
+        break;
897
+      case 112:
898
+        sprintf(name, "WSASetLastError");
899
+        break;
900
+      case 113:
901
+        sprintf(name, "WSACancelBlockingCall");
902
+        break;
903
+      case 114:
904
+        sprintf(name, "WSAIsBlocking");
905
+        break;
906
+      case 115:
907
+        sprintf(name, "WSAStartup");
908
+        break;
909
+      case 116:
910
+        sprintf(name, "WSACleanup");
911
+        break;
912
+      case 151:
913
+        sprintf(name, "__WSAFDIsSet");
914
+        break;
915
+      case 500:
916
+        sprintf(name, "WEP");
917
+        break;
918
+      default:
919
+        break;
920
+    }
921
+  }
922
+  else if (strncasecmp(dll, "oleaut32.dll", 12) == 0)
923
+  {
924
+    switch (ord) {
925
+      case 2:
926
+        sprintf(name, "SysAllocString");
927
+        break;
928
+      case 3:
929
+        sprintf(name, "SysReAllocString");
930
+        break;
931
+      case 4:
932
+        sprintf(name, "SysAllocStringLen");
933
+        break;
934
+      case 5:
935
+        sprintf(name, "SysReAllocStringLen");
936
+        break;
937
+      case 6:
938
+        sprintf(name, "SysFreeString");
939
+        break;
940
+      case 7:
941
+        sprintf(name, "SysStringLen");
942
+        break;
943
+      case 8:
944
+        sprintf(name, "VariantInit");
945
+        break;
946
+      case 9:
947
+        sprintf(name, "VariantClear");
948
+        break;
949
+      case 10:
950
+        sprintf(name, "VariantCopy");
951
+        break;
952
+      case 11:
953
+        sprintf(name, "VariantCopyInd");
954
+        break;
955
+      case 12:
956
+        sprintf(name, "VariantChangeType");
957
+        break;
958
+      case 13:
959
+        sprintf(name, "VariantTimeToDosDateTime");
960
+        break;
961
+      case 14:
962
+        sprintf(name, "DosDateTimeToVariantTime");
963
+        break;
964
+      case 15:
965
+        sprintf(name, "SafeArrayCreate");
966
+        break;
967
+      case 16:
968
+        sprintf(name, "SafeArrayDestroy");
969
+        break;
970
+      case 17:
971
+        sprintf(name, "SafeArrayGetDim");
972
+        break;
973
+      case 18:
974
+        sprintf(name, "SafeArrayGetElemsize");
975
+        break;
976
+      case 19:
977
+        sprintf(name, "SafeArrayGetUBound");
978
+        break;
979
+      case 20:
980
+        sprintf(name, "SafeArrayGetLBound");
981
+        break;
982
+      case 21:
983
+        sprintf(name, "SafeArrayLock");
984
+        break;
985
+      case 22:
986
+        sprintf(name, "SafeArrayUnlock");
987
+        break;
988
+      case 23:
989
+        sprintf(name, "SafeArrayAccessData");
990
+        break;
991
+      case 24:
992
+        sprintf(name, "SafeArrayUnaccessData");
993
+        break;
994
+      case 25:
995
+        sprintf(name, "SafeArrayGetElement");
996
+        break;
997
+      case 26:
998
+        sprintf(name, "SafeArrayPutElement");
999
+        break;
1000
+      case 27:
1001
+        sprintf(name, "SafeArrayCopy");
1002
+        break;
1003
+      case 28:
1004
+        sprintf(name, "DispGetParam");
1005
+        break;
1006
+      case 29:
1007
+        sprintf(name, "DispGetIDsOfNames");
1008
+        break;
1009
+      case 30:
1010
+        sprintf(name, "DispInvoke");
1011
+        break;
1012
+      case 31:
1013
+        sprintf(name, "CreateDispTypeInfo");
1014
+        break;
1015
+      case 32:
1016
+        sprintf(name, "CreateStdDispatch");
1017
+        break;
1018
+      case 33:
1019
+        sprintf(name, "RegisterActiveObject");
1020
+        break;
1021
+      case 34:
1022
+        sprintf(name, "RevokeActiveObject");
1023
+        break;
1024
+      case 35:
1025
+        sprintf(name, "GetActiveObject");
1026
+        break;
1027
+      case 36:
1028
+        sprintf(name, "SafeArrayAllocDescriptor");
1029
+        break;
1030
+      case 37:
1031
+        sprintf(name, "SafeArrayAllocData");
1032
+        break;
1033
+      case 38:
1034
+        sprintf(name, "SafeArrayDestroyDescriptor");
1035
+        break;
1036
+      case 39:
1037
+        sprintf(name, "SafeArrayDestroyData");
1038
+        break;
1039
+      case 40:
1040
+        sprintf(name, "SafeArrayRedim");
1041
+        break;
1042
+      case 41:
1043
+        sprintf(name, "SafeArrayAllocDescriptorEx");
1044
+        break;
1045
+      case 42:
1046
+        sprintf(name, "SafeArrayCreateEx");
1047
+        break;
1048
+      case 43:
1049
+        sprintf(name, "SafeArrayCreateVectorEx");
1050
+        break;
1051
+      case 44:
1052
+        sprintf(name, "SafeArraySetRecordInfo");
1053
+        break;
1054
+      case 45:
1055
+        sprintf(name, "SafeArrayGetRecordInfo");
1056
+        break;
1057
+      case 46:
1058
+        sprintf(name, "VarParseNumFromStr");
1059
+        break;
1060
+      case 47:
1061
+        sprintf(name, "VarNumFromParseNum");
1062
+        break;
1063
+      case 48:
1064
+        sprintf(name, "VarI2FromUI1");
1065
+        break;
1066
+      case 49:
1067
+        sprintf(name, "VarI2FromI4");
1068
+        break;
1069
+      case 50:
1070
+        sprintf(name, "VarI2FromR4");
1071
+        break;
1072
+      case 51:
1073
+        sprintf(name, "VarI2FromR8");
1074
+        break;
1075
+      case 52:
1076
+        sprintf(name, "VarI2FromCy");
1077
+        break;
1078
+      case 53:
1079
+        sprintf(name, "VarI2FromDate");
1080
+        break;
1081
+      case 54:
1082
+        sprintf(name, "VarI2FromStr");
1083
+        break;
1084
+      case 55:
1085
+        sprintf(name, "VarI2FromDisp");
1086
+        break;
1087
+      case 56:
1088
+        sprintf(name, "VarI2FromBool");
1089
+        break;
1090
+      case 57:
1091
+        sprintf(name, "SafeArraySetIID");
1092
+        break;
1093
+      case 58:
1094
+        sprintf(name, "VarI4FromUI1");
1095
+        break;
1096
+      case 59:
1097
+        sprintf(name, "VarI4FromI2");
1098
+        break;
1099
+      case 60:
1100
+        sprintf(name, "VarI4FromR4");
1101
+        break;
1102
+      case 61:
1103
+        sprintf(name, "VarI4FromR8");
1104
+        break;
1105
+      case 62:
1106
+        sprintf(name, "VarI4FromCy");
1107
+        break;
1108
+      case 63:
1109
+        sprintf(name, "VarI4FromDate");
1110
+        break;
1111
+      case 64:
1112
+        sprintf(name, "VarI4FromStr");
1113
+        break;
1114
+      case 65:
1115
+        sprintf(name, "VarI4FromDisp");
1116
+        break;
1117
+      case 66:
1118
+        sprintf(name, "VarI4FromBool");
1119
+        break;
1120
+      case 67:
1121
+        sprintf(name, "SafeArrayGetIID");
1122
+        break;
1123
+      case 68:
1124
+        sprintf(name, "VarR4FromUI1");
1125
+        break;
1126
+      case 69:
1127
+        sprintf(name, "VarR4FromI2");
1128
+        break;
1129
+      case 70:
1130
+        sprintf(name, "VarR4FromI4");
1131
+        break;
1132
+      case 71:
1133
+        sprintf(name, "VarR4FromR8");
1134
+        break;
1135
+      case 72:
1136
+        sprintf(name, "VarR4FromCy");
1137
+        break;
1138
+      case 73:
1139
+        sprintf(name, "VarR4FromDate");
1140
+        break;
1141
+      case 74:
1142
+        sprintf(name, "VarR4FromStr");
1143
+        break;
1144
+      case 75:
1145
+        sprintf(name, "VarR4FromDisp");
1146
+        break;
1147
+      case 76:
1148
+        sprintf(name, "VarR4FromBool");
1149
+        break;
1150
+      case 77:
1151
+        sprintf(name, "SafeArrayGetVartype");
1152
+        break;
1153
+      case 78:
1154
+        sprintf(name, "VarR8FromUI1");
1155
+        break;
1156
+      case 79:
1157
+        sprintf(name, "VarR8FromI2");
1158
+        break;
1159
+      case 80:
1160
+        sprintf(name, "VarR8FromI4");
1161
+        break;
1162
+      case 81:
1163
+        sprintf(name, "VarR8FromR4");
1164
+        break;
1165
+      case 82:
1166
+        sprintf(name, "VarR8FromCy");
1167
+        break;
1168
+      case 83:
1169
+        sprintf(name, "VarR8FromDate");
1170
+        break;
1171
+      case 84:
1172
+        sprintf(name, "VarR8FromStr");
1173
+        break;
1174
+      case 85:
1175
+        sprintf(name, "VarR8FromDisp");
1176
+        break;
1177
+      case 86:
1178
+        sprintf(name, "VarR8FromBool");
1179
+        break;
1180
+      case 87:
1181
+        sprintf(name, "VarFormat");
1182
+        break;
1183
+      case 88:
1184
+        sprintf(name, "VarDateFromUI1");
1185
+        break;
1186
+      case 89:
1187
+        sprintf(name, "VarDateFromI2");
1188
+        break;
1189
+      case 90:
1190
+        sprintf(name, "VarDateFromI4");
1191
+        break;
1192
+      case 91:
1193
+        sprintf(name, "VarDateFromR4");
1194
+        break;
1195
+      case 92:
1196
+        sprintf(name, "VarDateFromR8");
1197
+        break;
1198
+      case 93:
1199
+        sprintf(name, "VarDateFromCy");
1200
+        break;
1201
+      case 94:
1202
+        sprintf(name, "VarDateFromStr");
1203
+        break;
1204
+      case 95:
1205
+        sprintf(name, "VarDateFromDisp");
1206
+        break;
1207
+      case 96:
1208
+        sprintf(name, "VarDateFromBool");
1209
+        break;
1210
+      case 97:
1211
+        sprintf(name, "VarFormatDateTime");
1212
+        break;
1213
+      case 98:
1214
+        sprintf(name, "VarCyFromUI1");
1215
+        break;
1216
+      case 99:
1217
+        sprintf(name, "VarCyFromI2");
1218
+        break;
1219
+      case 100:
1220
+        sprintf(name, "VarCyFromI4");
1221
+        break;
1222
+      case 101:
1223
+        sprintf(name, "VarCyFromR4");
1224
+        break;
1225
+      case 102:
1226
+        sprintf(name, "VarCyFromR8");
1227
+        break;
1228
+      case 103:
1229
+        sprintf(name, "VarCyFromDate");
1230
+        break;
1231
+      case 104:
1232
+        sprintf(name, "VarCyFromStr");
1233
+        break;
1234
+      case 105:
1235
+        sprintf(name, "VarCyFromDisp");
1236
+        break;
1237
+      case 106:
1238
+        sprintf(name, "VarCyFromBool");
1239
+        break;
1240
+      case 107:
1241
+        sprintf(name, "VarFormatNumber");
1242
+        break;
1243
+      case 108:
1244
+        sprintf(name, "VarBstrFromUI1");
1245
+        break;
1246
+      case 109:
1247
+        sprintf(name, "VarBstrFromI2");
1248
+        break;
1249
+      case 110:
1250
+        sprintf(name, "VarBstrFromI4");
1251
+        break;
1252
+      case 111:
1253
+        sprintf(name, "VarBstrFromR4");
1254
+        break;
1255
+      case 112:
1256
+        sprintf(name, "VarBstrFromR8");
1257
+        break;
1258
+      case 113:
1259
+        sprintf(name, "VarBstrFromCy");
1260
+        break;
1261
+      case 114:
1262
+        sprintf(name, "VarBstrFromDate");
1263
+        break;
1264
+      case 115:
1265
+        sprintf(name, "VarBstrFromDisp");
1266
+        break;
1267
+      case 116:
1268
+        sprintf(name, "VarBstrFromBool");
1269
+        break;
1270
+      case 117:
1271
+        sprintf(name, "VarFormatPercent");
1272
+        break;
1273
+      case 118:
1274
+        sprintf(name, "VarBoolFromUI1");
1275
+        break;
1276
+      case 119:
1277
+        sprintf(name, "VarBoolFromI2");
1278
+        break;
1279
+      case 120:
1280
+        sprintf(name, "VarBoolFromI4");
1281
+        break;
1282
+      case 121:
1283
+        sprintf(name, "VarBoolFromR4");
1284
+        break;
1285
+      case 122:
1286
+        sprintf(name, "VarBoolFromR8");
1287
+        break;
1288
+      case 123:
1289
+        sprintf(name, "VarBoolFromDate");
1290
+        break;
1291
+      case 124:
1292
+        sprintf(name, "VarBoolFromCy");
1293
+        break;
1294
+      case 125:
1295
+        sprintf(name, "VarBoolFromStr");
1296
+        break;
1297
+      case 126:
1298
+        sprintf(name, "VarBoolFromDisp");
1299
+        break;
1300
+      case 127:
1301
+        sprintf(name, "VarFormatCurrency");
1302
+        break;
1303
+      case 128:
1304
+        sprintf(name, "VarWeekdayName");
1305
+        break;
1306
+      case 129:
1307
+        sprintf(name, "VarMonthName");
1308
+        break;
1309
+      case 130:
1310
+        sprintf(name, "VarUI1FromI2");
1311
+        break;
1312
+      case 131:
1313
+        sprintf(name, "VarUI1FromI4");
1314
+        break;
1315
+      case 132:
1316
+        sprintf(name, "VarUI1FromR4");
1317
+        break;
1318
+      case 133:
1319
+        sprintf(name, "VarUI1FromR8");
1320
+        break;
1321
+      case 134:
1322
+        sprintf(name, "VarUI1FromCy");
1323
+        break;
1324
+      case 135:
1325
+        sprintf(name, "VarUI1FromDate");
1326
+        break;
1327
+      case 136:
1328
+        sprintf(name, "VarUI1FromStr");
1329
+        break;
1330
+      case 137:
1331
+        sprintf(name, "VarUI1FromDisp");
1332
+        break;
1333
+      case 138:
1334
+        sprintf(name, "VarUI1FromBool");
1335
+        break;
1336
+      case 139:
1337
+        sprintf(name, "VarFormatFromTokens");
1338
+        break;
1339
+      case 140:
1340
+        sprintf(name, "VarTokenizeFormatString");
1341
+        break;
1342
+      case 141:
1343
+        sprintf(name, "VarAdd");
1344
+        break;
1345
+      case 142:
1346
+        sprintf(name, "VarAnd");
1347
+        break;
1348
+      case 143:
1349
+        sprintf(name, "VarDiv");
1350
+        break;
1351
+      case 144:
1352
+        sprintf(name, "DllCanUnloadNow");
1353
+        break;
1354
+      case 145:
1355
+        sprintf(name, "DllGetClassObject");
1356
+        break;
1357
+      case 146:
1358
+        sprintf(name, "DispCallFunc");
1359
+        break;
1360
+      case 147:
1361
+        sprintf(name, "VariantChangeTypeEx");
1362
+        break;
1363
+      case 148:
1364
+        sprintf(name, "SafeArrayPtrOfIndex");
1365
+        break;
1366
+      case 149:
1367
+        sprintf(name, "SysStringByteLen");
1368
+        break;
1369
+      case 150:
1370
+        sprintf(name, "SysAllocStringByteLen");
1371
+        break;
1372
+      case 151:
1373
+        sprintf(name, "DllRegisterServer");
1374
+        break;
1375
+      case 152:
1376
+        sprintf(name, "VarEqv");
1377
+        break;
1378
+      case 153:
1379
+        sprintf(name, "VarIdiv");
1380
+        break;
1381
+      case 154:
1382
+        sprintf(name, "VarImp");
1383
+        break;
1384
+      case 155:
1385
+        sprintf(name, "VarMod");
1386
+        break;
1387
+      case 156:
1388
+        sprintf(name, "VarMul");
1389
+        break;
1390
+      case 157:
1391
+        sprintf(name, "VarOr");
1392
+        break;
1393
+      case 158:
1394
+        sprintf(name, "VarPow");
1395
+        break;
1396
+      case 159:
1397
+        sprintf(name, "VarSub");
1398
+        break;
1399
+      case 160:
1400
+        sprintf(name, "CreateTypeLib");
1401
+        break;
1402
+      case 161:
1403
+        sprintf(name, "LoadTypeLib");
1404
+        break;
1405
+      case 162:
1406
+        sprintf(name, "LoadRegTypeLib");
1407
+        break;
1408
+      case 163:
1409
+        sprintf(name, "RegisterTypeLib");
1410
+        break;
1411
+      case 164:
1412
+        sprintf(name, "QueryPathOfRegTypeLib");
1413
+        break;
1414
+      case 165:
1415
+        sprintf(name, "LHashValOfNameSys");
1416
+        break;
1417
+      case 166:
1418
+        sprintf(name, "LHashValOfNameSysA");
1419
+        break;
1420
+      case 167:
1421
+        sprintf(name, "VarXor");
1422
+        break;
1423
+      case 168:
1424
+        sprintf(name, "VarAbs");
1425
+        break;
1426
+      case 169:
1427
+        sprintf(name, "VarFix");
1428
+        break;
1429
+      case 170:
1430
+        sprintf(name, "OaBuildVersion");
1431
+        break;
1432
+      case 171:
1433
+        sprintf(name, "ClearCustData");
1434
+        break;
1435
+      case 172:
1436
+        sprintf(name, "VarInt");
1437
+        break;
1438
+      case 173:
1439
+        sprintf(name, "VarNeg");
1440
+        break;
1441
+      case 174:
1442
+        sprintf(name, "VarNot");
1443
+        break;
1444
+      case 175:
1445
+        sprintf(name, "VarRound");
1446
+        break;
1447
+      case 176:
1448
+        sprintf(name, "VarCmp");
1449
+        break;
1450
+      case 177:
1451
+        sprintf(name, "VarDecAdd");
1452
+        break;
1453
+      case 178:
1454
+        sprintf(name, "VarDecDiv");
1455
+        break;
1456
+      case 179:
1457
+        sprintf(name, "VarDecMul");
1458
+        break;
1459
+      case 180:
1460
+        sprintf(name, "CreateTypeLib2");
1461
+        break;
1462
+      case 181:
1463
+        sprintf(name, "VarDecSub");
1464
+        break;
1465
+      case 182:
1466
+        sprintf(name, "VarDecAbs");
1467
+        break;
1468
+      case 183:
1469
+        sprintf(name, "LoadTypeLibEx");
1470
+        break;
1471
+      case 184:
1472
+        sprintf(name, "SystemTimeToVariantTime");
1473
+        break;
1474
+      case 185:
1475
+        sprintf(name, "VariantTimeToSystemTime");
1476
+        break;
1477
+      case 186:
1478
+        sprintf(name, "UnRegisterTypeLib");
1479
+        break;
1480
+      case 187:
1481
+        sprintf(name, "VarDecFix");
1482
+        break;
1483
+      case 188:
1484
+        sprintf(name, "VarDecInt");
1485
+        break;
1486
+      case 189:
1487
+        sprintf(name, "VarDecNeg");
1488
+        break;
1489
+      case 190:
1490
+        sprintf(name, "VarDecFromUI1");
1491
+        break;
1492
+      case 191:
1493
+        sprintf(name, "VarDecFromI2");
1494
+        break;
1495
+      case 192:
1496
+        sprintf(name, "VarDecFromI4");
1497
+        break;
1498
+      case 193:
1499
+        sprintf(name, "VarDecFromR4");
1500
+        break;
1501
+      case 194:
1502
+        sprintf(name, "VarDecFromR8");
1503
+        break;
1504
+      case 195:
1505
+        sprintf(name, "VarDecFromDate");
1506
+        break;
1507
+      case 196:
1508
+        sprintf(name, "VarDecFromCy");
1509
+        break;
1510
+      case 197:
1511
+        sprintf(name, "VarDecFromStr");
1512
+        break;
1513
+      case 198:
1514
+        sprintf(name, "VarDecFromDisp");
1515
+        break;
1516
+      case 199:
1517
+        sprintf(name, "VarDecFromBool");
1518
+        break;
1519
+      case 200:
1520
+        sprintf(name, "GetErrorInfo");
1521
+        break;
1522
+      case 201:
1523
+        sprintf(name, "SetErrorInfo");
1524
+        break;
1525
+      case 202:
1526
+        sprintf(name, "CreateErrorInfo");
1527
+        break;
1528
+      case 203:
1529
+        sprintf(name, "VarDecRound");
1530
+        break;
1531
+      case 204:
1532
+        sprintf(name, "VarDecCmp");
1533
+        break;
1534
+      case 205:
1535
+        sprintf(name, "VarI2FromI1");
1536
+        break;
1537
+      case 206:
1538
+        sprintf(name, "VarI2FromUI2");
1539
+        break;
1540
+      case 207:
1541
+        sprintf(name, "VarI2FromUI4");
1542
+        break;
1543
+      case 208:
1544
+        sprintf(name, "VarI2FromDec");
1545
+        break;
1546
+      case 209:
1547
+        sprintf(name, "VarI4FromI1");
1548
+        break;
1549
+      case 210:
1550
+        sprintf(name, "VarI4FromUI2");
1551
+        break;
1552
+      case 211:
1553
+        sprintf(name, "VarI4FromUI4");
1554
+        break;
1555
+      case 212:
1556
+        sprintf(name, "VarI4FromDec");
1557
+        break;
1558
+      case 213:
1559
+        sprintf(name, "VarR4FromI1");
1560
+        break;
1561
+      case 214:
1562
+        sprintf(name, "VarR4FromUI2");
1563
+        break;
1564
+      case 215:
1565
+        sprintf(name, "VarR4FromUI4");
1566
+        break;
1567
+      case 216:
1568
+        sprintf(name, "VarR4FromDec");
1569
+        break;
1570
+      case 217:
1571
+        sprintf(name, "VarR8FromI1");
1572
+        break;
1573
+      case 218:
1574
+        sprintf(name, "VarR8FromUI2");
1575
+        break;
1576
+      case 219:
1577
+        sprintf(name, "VarR8FromUI4");
1578
+        break;
1579
+      case 220:
1580
+        sprintf(name, "VarR8FromDec");
1581
+        break;
1582
+      case 221:
1583
+        sprintf(name, "VarDateFromI1");
1584
+        break;
1585
+      case 222:
1586
+        sprintf(name, "VarDateFromUI2");
1587
+        break;
1588
+      case 223:
1589
+        sprintf(name, "VarDateFromUI4");
1590
+        break;
1591
+      case 224:
1592
+        sprintf(name, "VarDateFromDec");
1593
+        break;
1594
+      case 225:
1595
+        sprintf(name, "VarCyFromI1");
1596
+        break;
1597
+      case 226:
1598
+        sprintf(name, "VarCyFromUI2");
1599
+        break;
1600
+      case 227:
1601
+        sprintf(name, "VarCyFromUI4");
1602
+        break;
1603
+      case 228:
1604
+        sprintf(name, "VarCyFromDec");
1605
+        break;
1606
+      case 229:
1607
+        sprintf(name, "VarBstrFromI1");
1608
+        break;
1609
+      case 230:
1610
+        sprintf(name, "VarBstrFromUI2");
1611
+        break;
1612
+      case 231:
1613
+        sprintf(name, "VarBstrFromUI4");
1614
+        break;
1615
+      case 232:
1616
+        sprintf(name, "VarBstrFromDec");
1617
+        break;
1618
+      case 233:
1619
+        sprintf(name, "VarBoolFromI1");
1620
+        break;
1621
+      case 234:
1622
+        sprintf(name, "VarBoolFromUI2");
1623
+        break;
1624
+      case 235:
1625
+        sprintf(name, "VarBoolFromUI4");
1626
+        break;
1627
+      case 236:
1628
+        sprintf(name, "VarBoolFromDec");
1629
+        break;
1630
+      case 237:
1631
+        sprintf(name, "VarUI1FromI1");
1632
+        break;
1633
+      case 238:
1634
+        sprintf(name, "VarUI1FromUI2");
1635
+        break;
1636
+      case 239:
1637
+        sprintf(name, "VarUI1FromUI4");
1638
+        break;
1639
+      case 240:
1640
+        sprintf(name, "VarUI1FromDec");
1641
+        break;
1642
+      case 241:
1643
+        sprintf(name, "VarDecFromI1");
1644
+        break;
1645
+      case 242:
1646
+        sprintf(name, "VarDecFromUI2");
1647
+        break;
1648
+      case 243:
1649
+        sprintf(name, "VarDecFromUI4");
1650
+        break;
1651
+      case 244:
1652
+        sprintf(name, "VarI1FromUI1");
1653
+        break;
1654
+      case 245:
1655
+        sprintf(name, "VarI1FromI2");
1656
+        break;
1657
+      case 246:
1658
+        sprintf(name, "VarI1FromI4");
1659
+        break;
1660
+      case 247:
1661
+        sprintf(name, "VarI1FromR4");
1662
+        break;
1663
+      case 248:
1664
+        sprintf(name, "VarI1FromR8");
1665
+        break;
1666
+      case 249:
1667
+        sprintf(name, "VarI1FromDate");
1668
+        break;
1669
+      case 250:
1670
+        sprintf(name, "VarI1FromCy");
1671
+        break;
1672
+      case 251:
1673
+        sprintf(name, "VarI1FromStr");
1674
+        break;
1675
+      case 252:
1676
+        sprintf(name, "VarI1FromDisp");
1677
+        break;
1678
+      case 253:
1679
+        sprintf(name, "VarI1FromBool");
1680
+        break;
1681
+      case 254:
1682
+        sprintf(name, "VarI1FromUI2");
1683
+        break;
1684
+      case 255:
1685
+        sprintf(name, "VarI1FromUI4");
1686
+        break;
1687
+      case 256:
1688
+        sprintf(name, "VarI1FromDec");
1689
+        break;
1690
+      case 257:
1691
+        sprintf(name, "VarUI2FromUI1");
1692
+        break;
1693
+      case 258:
1694
+        sprintf(name, "VarUI2FromI2");
1695
+        break;
1696
+      case 259:
1697
+        sprintf(name, "VarUI2FromI4");
1698
+        break;
1699
+      case 260:
1700
+        sprintf(name, "VarUI2FromR4");
1701
+        break;
1702
+      case 261:
1703
+        sprintf(name, "VarUI2FromR8");
1704
+        break;
1705
+      case 262:
1706
+        sprintf(name, "VarUI2FromDate");
1707
+        break;
1708
+      case 263:
1709
+        sprintf(name, "VarUI2FromCy");
1710
+        break;
1711
+      case 264:
1712
+        sprintf(name, "VarUI2FromStr");
1713
+        break;
1714
+      case 265:
1715
+        sprintf(name, "VarUI2FromDisp");
1716
+        break;
1717
+      case 266:
1718
+        sprintf(name, "VarUI2FromBool");
1719
+        break;
1720
+      case 267:
1721
+        sprintf(name, "VarUI2FromI1");
1722
+        break;
1723
+      case 268:
1724
+        sprintf(name, "VarUI2FromUI4");
1725
+        break;
1726
+      case 269:
1727
+        sprintf(name, "VarUI2FromDec");
1728
+        break;
1729
+      case 270:
1730
+        sprintf(name, "VarUI4FromUI1");
1731
+        break;
1732
+      case 271:
1733
+        sprintf(name, "VarUI4FromI2");
1734
+        break;
1735
+      case 272:
1736
+        sprintf(name, "VarUI4FromI4");
1737
+        break;
1738
+      case 273:
1739
+        sprintf(name, "VarUI4FromR4");
1740
+        break;
1741
+      case 274:
1742
+        sprintf(name, "VarUI4FromR8");
1743
+        break;
1744
+      case 275:
1745
+        sprintf(name, "VarUI4FromDate");
1746
+        break;
1747
+      case 276:
1748
+        sprintf(name, "VarUI4FromCy");
1749
+        break;
1750
+      case 277:
1751
+        sprintf(name, "VarUI4FromStr");
1752
+        break;
1753
+      case 278:
1754
+        sprintf(name, "VarUI4FromDisp");
1755
+        break;
1756
+      case 279:
1757
+        sprintf(name, "VarUI4FromBool");
1758
+        break;
1759
+      case 280:
1760
+        sprintf(name, "VarUI4FromI1");
1761
+        break;
1762
+      case 281:
1763
+        sprintf(name, "VarUI4FromUI2");
1764
+        break;
1765
+      case 282:
1766
+        sprintf(name, "VarUI4FromDec");
1767
+        break;
1768
+      case 283:
1769
+        sprintf(name, "BSTR_UserSize");
1770
+        break;
1771
+      case 284:
1772
+        sprintf(name, "BSTR_UserMarshal");
1773
+        break;
1774
+      case 285:
1775
+        sprintf(name, "BSTR_UserUnmarshal");
1776
+        break;
1777
+      case 286:
1778
+        sprintf(name, "BSTR_UserFree");
1779
+        break;
1780
+      case 287:
1781
+        sprintf(name, "VARIANT_UserSize");
1782
+        break;
1783
+      case 288:
1784
+        sprintf(name, "VARIANT_UserMarshal");
1785
+        break;
1786
+      case 289:
1787
+        sprintf(name, "VARIANT_UserUnmarshal");
1788
+        break;
1789
+      case 290:
1790
+        sprintf(name, "VARIANT_UserFree");
1791
+        break;
1792
+      case 291:
1793
+        sprintf(name, "LPSAFEARRAY_UserSize");
1794
+        break;
1795
+      case 292:
1796
+        sprintf(name, "LPSAFEARRAY_UserMarshal");
1797
+        break;
1798
+      case 293:
1799
+        sprintf(name, "LPSAFEARRAY_UserUnmarshal");
1800
+        break;
1801
+      case 294:
1802
+        sprintf(name, "LPSAFEARRAY_UserFree");
1803
+        break;
1804
+      case 295:
1805
+        sprintf(name, "LPSAFEARRAY_Size");
1806
+        break;
1807
+      case 296:
1808
+        sprintf(name, "LPSAFEARRAY_Marshal");
1809
+        break;
1810
+      case 297:
1811
+        sprintf(name, "LPSAFEARRAY_Unmarshal");
1812
+        break;
1813
+      case 298:
1814
+        sprintf(name, "VarDecCmpR8");
1815
+        break;
1816
+      case 299:
1817
+        sprintf(name, "VarCyAdd");
1818
+        break;
1819
+      case 300:
1820
+        sprintf(name, "DllUnregisterServer");
1821
+        break;
1822
+      case 301:
1823
+        sprintf(name, "OACreateTypeLib2");
1824
+        break;
1825
+      case 303:
1826
+        sprintf(name, "VarCyMul");
1827
+        break;
1828
+      case 304:
1829
+        sprintf(name, "VarCyMulI4");
1830
+        break;
1831
+      case 305:
1832
+        sprintf(name, "VarCySub");
1833
+        break;
1834
+      case 306:
1835
+        sprintf(name, "VarCyAbs");
1836
+        break;
1837
+      case 307:
1838
+        sprintf(name, "VarCyFix");
1839
+        break;
1840
+      case 308:
1841
+        sprintf(name, "VarCyInt");
1842
+        break;
1843
+      case 309:
1844
+        sprintf(name, "VarCyNeg");
1845
+        break;
1846
+      case 310:
1847
+        sprintf(name, "VarCyRound");
1848
+        break;
1849
+      case 311:
1850
+        sprintf(name, "VarCyCmp");
1851
+        break;
1852
+      case 312:
1853
+        sprintf(name, "VarCyCmpR8");
1854
+        break;
1855
+      case 313:
1856
+        sprintf(name, "VarBstrCat");
1857
+        break;
1858
+      case 314:
1859
+        sprintf(name, "VarBstrCmp");
1860
+        break;
1861
+      case 315:
1862
+        sprintf(name, "VarR8Pow");
1863
+        break;
1864
+      case 316:
1865
+        sprintf(name, "VarR4CmpR8");
1866
+        break;
1867
+      case 317:
1868
+        sprintf(name, "VarR8Round");
1869
+        break;
1870
+      case 318:
1871
+        sprintf(name, "VarCat");
1872
+        break;
1873
+      case 319:
1874
+        sprintf(name, "VarDateFromUdateEx");
1875
+        break;
1876
+      case 322:
1877
+        sprintf(name, "GetRecordInfoFromGuids");
1878
+        break;
1879
+      case 323:
1880
+        sprintf(name, "GetRecordInfoFromTypeInfo");
1881
+        break;
1882
+      case 325:
1883
+        sprintf(name, "SetVarConversionLocaleSetting");
1884
+        break;
1885
+      case 326:
1886
+        sprintf(name, "GetVarConversionLocaleSetting");
1887
+        break;
1888
+      case 327:
1889
+        sprintf(name, "SetOaNoCache");
1890
+        break;
1891
+      case 329:
1892
+        sprintf(name, "VarCyMulI8");
1893
+        break;
1894
+      case 330:
1895
+        sprintf(name, "VarDateFromUdate");
1896
+        break;
1897
+      case 331:
1898
+        sprintf(name, "VarUdateFromDate");
1899
+        break;
1900
+      case 332:
1901
+        sprintf(name, "GetAltMonthNames");
1902
+        break;
1903
+      case 333:
1904
+        sprintf(name, "VarI8FromUI1");
1905
+        break;
1906
+      case 334:
1907
+        sprintf(name, "VarI8FromI2");
1908
+        break;
1909
+      case 335:
1910
+        sprintf(name, "VarI8FromR4");
1911
+        break;
1912
+      case 336:
1913
+        sprintf(name, "VarI8FromR8");
1914
+        break;
1915
+      case 337:
1916
+        sprintf(name, "VarI8FromCy");
1917
+        break;
1918
+      case 338:
1919
+        sprintf(name, "VarI8FromDate");
1920
+        break;
1921
+      case 339:
1922
+        sprintf(name, "VarI8FromStr");
1923
+        break;
1924
+      case 340:
1925
+        sprintf(name, "VarI8FromDisp");
1926
+        break;
1927
+      case 341:
1928
+        sprintf(name, "VarI8FromBool");
1929
+        break;
1930
+      case 342:
1931
+        sprintf(name, "VarI8FromI1");
1932
+        break;
1933
+      case 343:
1934
+        sprintf(name, "VarI8FromUI2");
1935
+        break;
1936
+      case 344:
1937
+        sprintf(name, "VarI8FromUI4");
1938
+        break;
1939
+      case 345:
1940
+        sprintf(name, "VarI8FromDec");
1941
+        break;
1942
+      case 346:
1943
+        sprintf(name, "VarI2FromI8");
1944
+        break;
1945
+      case 347:
1946
+        sprintf(name, "VarI2FromUI8");
1947
+        break;
1948
+      case 348:
1949
+        sprintf(name, "VarI4FromI8");
1950
+        break;
1951
+      case 349:
1952
+        sprintf(name, "VarI4FromUI8");
1953
+        break;
1954
+      case 360:
1955
+        sprintf(name, "VarR4FromI8");
1956
+        break;
1957
+      case 361:
1958
+        sprintf(name, "VarR4FromUI8");
1959
+        break;
1960
+      case 362:
1961
+        sprintf(name, "VarR8FromI8");
1962
+        break;
1963
+      case 363:
1964
+        sprintf(name, "VarR8FromUI8");
1965
+        break;
1966
+      case 364:
1967
+        sprintf(name, "VarDateFromI8");
1968
+        break;
1969
+      case 365:
1970
+        sprintf(name, "VarDateFromUI8");
1971
+        break;
1972
+      case 366:
1973
+        sprintf(name, "VarCyFromI8");
1974
+        break;
1975
+      case 367:
1976
+        sprintf(name, "VarCyFromUI8");
1977
+        break;
1978
+      case 368:
1979
+        sprintf(name, "VarBstrFromI8");
1980
+        break;
1981
+      case 369:
1982
+        sprintf(name, "VarBstrFromUI8");
1983
+        break;
1984
+      case 370:
1985
+        sprintf(name, "VarBoolFromI8");
1986
+        break;
1987
+      case 371:
1988
+        sprintf(name, "VarBoolFromUI8");
1989
+        break;
1990
+      case 372:
1991
+        sprintf(name, "VarUI1FromI8");
1992
+        break;
1993
+      case 373:
1994
+        sprintf(name, "VarUI1FromUI8");
1995
+        break;
1996
+      case 374:
1997
+        sprintf(name, "VarDecFromI8");
1998
+        break;
1999
+      case 375:
2000
+        sprintf(name, "VarDecFromUI8");
2001
+        break;
2002
+      case 376:
2003
+        sprintf(name, "VarI1FromI8");
2004
+        break;
2005
+      case 377:
2006
+        sprintf(name, "VarI1FromUI8");
2007
+        break;
2008
+      case 378:
2009
+        sprintf(name, "VarUI2FromI8");
2010
+        break;
2011
+      case 379:
2012
+        sprintf(name, "VarUI2FromUI8");
2013
+        break;
2014
+      case 401:
2015
+        sprintf(name, "OleLoadPictureEx");
2016
+        break;
2017
+      case 402:
2018
+        sprintf(name, "OleLoadPictureFileEx");
2019
+        break;
2020
+      case 411:
2021
+        sprintf(name, "SafeArrayCreateVector");
2022
+        break;
2023
+      case 412:
2024
+        sprintf(name, "SafeArrayCopyData");
2025
+        break;
2026
+      case 413:
2027
+        sprintf(name, "VectorFromBstr");
2028
+        break;
2029
+      case 414:
2030
+        sprintf(name, "BstrFromVector");
2031
+        break;
2032
+      case 415:
2033
+        sprintf(name, "OleIconToCursor");
2034
+        break;
2035
+      case 416:
2036
+        sprintf(name, "OleCreatePropertyFrameIndirect");
2037
+        break;
2038
+      case 417:
2039
+        sprintf(name, "OleCreatePropertyFrame");
2040
+        break;
2041
+      case 418:
2042
+        sprintf(name, "OleLoadPicture");
2043
+        break;
2044
+      case 419:
2045
+        sprintf(name, "OleCreatePictureIndirect");
2046
+        break;
2047
+      case 420:
2048
+        sprintf(name, "OleCreateFontIndirect");
2049
+        break;
2050
+      case 421:
2051
+        sprintf(name, "OleTranslateColor");
2052
+        break;
2053
+      case 422:
2054
+        sprintf(name, "OleLoadPictureFile");
2055
+        break;
2056
+      case 423:
2057
+        sprintf(name, "OleSavePictureFile");
2058
+        break;
2059
+      case 424:
2060
+        sprintf(name, "OleLoadPicturePath");
2061
+        break;
2062
+      case 425:
2063
+        sprintf(name, "VarUI4FromI8");
2064
+        break;
2065
+      case 426:
2066
+        sprintf(name, "VarUI4FromUI8");
2067
+        break;
2068
+      case 427:
2069
+        sprintf(name, "VarI8FromUI8");
2070
+        break;
2071
+      case 428:
2072
+        sprintf(name, "VarUI8FromI8");
2073
+        break;
2074
+      case 429:
2075
+        sprintf(name, "VarUI8FromUI1");
2076
+        break;
2077
+      case 430:
2078
+        sprintf(name, "VarUI8FromI2");
2079
+        break;
2080
+      case 431:
2081
+        sprintf(name, "VarUI8FromR4");
2082
+        break;
2083
+      case 432:
2084
+        sprintf(name, "VarUI8FromR8");
2085
+        break;
2086
+      case 433:
2087
+        sprintf(name, "VarUI8FromCy");
2088
+        break;
2089
+      case 434:
2090
+        sprintf(name, "VarUI8FromDate");
2091
+        break;
2092
+      case 435:
2093
+        sprintf(name, "VarUI8FromStr");
2094
+        break;
2095
+      case 436:
2096
+        sprintf(name, "VarUI8FromDisp");
2097
+        break;
2098
+      case 437:
2099
+        sprintf(name, "VarUI8FromBool");
2100
+        break;
2101
+      case 438:
2102
+        sprintf(name, "VarUI8FromI1");
2103
+        break;
2104
+      case 439:
2105
+        sprintf(name, "VarUI8FromUI2");
2106
+        break;
2107
+      case 440:
2108
+        sprintf(name, "VarUI8FromUI4");
2109
+        break;
2110
+      case 441:
2111
+        sprintf(name, "VarUI8FromDec");
2112
+        break;
2113
+      case 442:
2114
+        sprintf(name, "RegisterTypeLibForUser");
2115
+        break;
2116
+      case 443:
2117
+        sprintf(name, "UnRegisterTypeLibForUser");
2118
+        break;
2119
+      default:
2120
+        break;
2121
+    }
2122
+  }
2123
+
2124
+  if (name[0] == '\0')
2125
+    sprintf(name, "ord%u", ord);
2126
+
2127
+  return cli_strdup(name);    
2128
+}
2129
+
2130
+#define PE_MAXIMPORTS  1024
2131
+#define PE_MAXNAMESIZE 256
2132
+static inline int scan_pe_impfuncs(cli_ctx *ctx, void *md5ctx, struct pe_image_import_descriptor *image, char *dllname, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size, int pe_plus, int *first) {
2133
+    uint32_t toff, offset;
2134
+    fmap_t *map = *ctx->fmap;
2135
+    size_t dlllen = 0, fsize = map->len;
2136
+    int i, j, err, num_funcs = 0;
2137
+    const char *buffer;
2138
+
2139
+    toff = cli_rawaddr(image->u.OriginalFirstThunk, exe_sections, nsections, &err, fsize, hdr_size);
2140
+    if (err)
2141
+        toff = cli_rawaddr(image->FirstThunk, exe_sections, nsections, &err, fsize, hdr_size);
2142
+    if (err) {
2143
+        cli_dbgmsg("IMPTBL: invalid rva for image first thunk\n");
2144
+        return CL_SUCCESS;
2145
+    }
2146
+
2147
+    if (!pe_plus) {
2148
+        struct pe_image_thunk32 thunk32;
2149
+
2150
+        while (fmap_readn(map, &thunk32, toff, sizeof(struct pe_image_thunk32)) == sizeof(struct pe_image_thunk32) &&
2151
+               thunk32.u.Ordinal != 0 && num_funcs < PE_MAXIMPORTS) {
2152
+            char *funcname = NULL;
2153
+            toff += sizeof(struct pe_image_thunk32);
2154
+
2155
+            if (!(thunk32.u.Ordinal & IMAGE_ORDINAL_FLAG32)) {
2156
+                offset = cli_rawaddr(thunk32.u.Function, exe_sections, nsections, &err, fsize, hdr_size);
2157
+
2158
+                if (offset >= 0) {
2159
+                    /* Hint field is a uint16_t and precedes the Name field */
2160
+                    if ((buffer = fmap_need_off_once(map, offset+sizeof(uint16_t), MIN(PE_MAXNAMESIZE, fsize-offset))) != NULL) {
2161
+                        funcname = strndup(buffer, MIN(PE_MAXNAMESIZE, fsize-offset));
2162
+                        if (funcname == NULL) {
2163
+                            cli_dbgmsg("IMPTBL: cannot duplicate function name\n");
2164
+                            return CL_EMEM;
2165
+                        }
2166
+                    }
2167
+                }
2168
+            } else {
2169
+                /* ordinal lookup */
2170
+                funcname = pe_ordinal(dllname, thunk32.u.Ordinal & 0xFFFF);
2171
+                if (funcname == NULL) {
2172
+                    cli_dbgmsg("IMPTBL: cannot duplicate function name\n");
2173
+                    return CL_EMEM;
2174
+                }
2175
+            }
2176
+
2177
+            if (funcname) {
2178
+                char *fname;
2179
+                size_t funclen;
2180
+
2181
+                /* JSON TOMFOOLERY */
2182
+                //cli_dbgmsg("IMPTBL: FUNC: %s\n", funcname);
2183
+
2184
+                if (dlllen == 0) {
2185
+                    char* ext = strstr(dllname, ".");
2186
+
2187
+                    if (ext && (strncasecmp(ext, ".ocx", 4) == 0 ||
2188
+                                strncasecmp(ext, ".sys", 4) == 0 ||
2189
+                                strncasecmp(ext, ".dll", 4) == 0))
2190
+                        dlllen = ext - dllname;
2191
+                    else
2192
+                        dlllen = strlen(dllname);
2193
+                }
2194
+
2195
+                funclen = strlen(funcname);
2196
+
2197
+                fname = cli_calloc(funclen + dlllen + 3, sizeof(char));
2198
+                if (fname == NULL) {
2199
+                    cli_dbgmsg("IMPTBL: cannot allocate memory for imphash string\n");
2200
+                    return CL_EMEM;
2201
+                }
2202
+                j = 0;
2203
+                if (!*first)
2204
+                    fname[j++] = ',';
2205
+                else
2206
+                    *first = 0;
2207
+                for (i = 0; i < dlllen; i++, j++)
2208
+                    fname[j] = tolower(dllname[i]);
2209
+                fname[j++] = '.';
2210
+                for (i = 0; i < funclen; i++, j++)
2211
+                    fname[j] = tolower(funcname[i]);
2212
+
2213
+                cli_dbgmsg("%u %s\n", strlen(fname), fname);
2214
+
2215
+                cl_update_hash(md5ctx, fname, strlen(fname));
2216
+
2217
+                free(fname);
2218
+                free(funcname);
2219
+            }
2220
+        }
2221
+    } else {
2222
+        struct pe_image_thunk64 thunk64;
2223
+
2224
+        while (fmap_readn(map, &thunk64, toff, sizeof(struct pe_image_thunk64)) == sizeof(struct pe_image_thunk64) &&
2225
+               thunk64.u.Ordinal != 0 && num_funcs < PE_MAXIMPORTS) {
2226
+            char *funcname = NULL;
2227
+            toff += sizeof(struct pe_image_thunk64);
2228
+
2229
+            if (!(thunk64.u.Ordinal & IMAGE_ORDINAL_FLAG32)) {
2230
+                offset = cli_rawaddr(thunk64.u.Function, exe_sections, nsections, &err, fsize, hdr_size);
2231
+
2232
+                if (offset >= 0) {
2233
+                    /* Hint field is a uint16_t and precedes the Name field */
2234
+                    if ((buffer = fmap_need_off_once(map, offset+sizeof(uint16_t), MIN(PE_MAXNAMESIZE, fsize-offset))) != NULL) {
2235
+                        funcname = strndup(buffer, MIN(PE_MAXNAMESIZE, fsize-offset));
2236
+                        if (funcname == NULL) {
2237
+                            cli_dbgmsg("IMPTBL: cannot duplicate function name\n");
2238
+                            return CL_EMEM;
2239
+                        }
2240
+                    }
2241
+                }
2242
+            } else {
2243
+                /* ordinal lookup */
2244
+                funcname = cli_strdup(pe_ordinal(dllname, thunk64.u.Ordinal & 0xFFFF));
2245
+                if (funcname == NULL) {
2246
+                    cli_dbgmsg("IMPTBL: cannot duplicate function name\n");
2247
+                    return CL_EMEM;
2248
+                }
2249
+            }
2250
+
2251
+            if (funcname) {
2252
+                char *fname;
2253
+                size_t funclen;
2254
+
2255
+                /* JSON TOMFOOLERY */
2256
+                //cli_dbgmsg("IMPTBL: FUNC: %s\n", funcname);
2257
+
2258
+                if (dlllen == 0) {
2259
+                    char* ext = strstr(dllname, ".");
2260
+
2261
+                    if (ext && (strncasecmp(ext, ".ocx", 4) == 0 ||
2262
+                                strncasecmp(ext, ".sys", 4) == 0 ||
2263
+                                strncasecmp(ext, ".dll", 4) == 0))
2264
+                        dlllen = ext - dllname;
2265
+                    else
2266
+                        dlllen = strlen(dllname);
2267
+                }
2268
+
2269
+                funclen = strlen(funcname);
2270
+
2271
+                fname = cli_calloc(funclen + dlllen + 3, sizeof(char));
2272
+                if (fname == NULL) {
2273
+                    cli_dbgmsg("IMPTBL: cannot allocate memory for imphash string\n");
2274
+                    return CL_EMEM;
2275
+                }
2276
+                j = 0;
2277
+                if (!*first)
2278
+                    fname[j++] = ',';
2279
+                else
2280
+                    *first = 0;
2281
+                for (i = 0; i < dlllen; i++, j++)
2282
+                    fname[j] = tolower(dllname[i]);
2283
+                fname[j++] = '.';
2284
+                for (i = 0; i < funclen; i++, j++)
2285
+                    fname[j] = tolower(funcname[i]);
2286
+
2287
+                cli_dbgmsg("%u %s\n", strlen(fname), fname);
2288
+
2289
+                cl_update_hash(md5ctx, fname, strlen(fname));
2290
+
2291
+                free(fname);
2292
+                free(funcname);
2293
+            }
2294
+        }
2295
+    }
2296
+
2297
+    return CL_SUCCESS;
2298
+}
2299
+
2300
+static int scan_pe_imptbl(cli_ctx *ctx, struct pe_image_data_dir *dirs, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size, int pe_plus) {
2301
+    struct pe_image_data_dir *datadir = &(dirs[1]);
2302
+    struct pe_image_import_descriptor *image;
2303
+    fmap_t *map = *ctx->fmap;
2304
+    size_t left, fsize = map->len;
2305
+    uint32_t impoff, offset;
2306
+    const char *impdes, *buffer;
2307
+    void *md5ctx;
2308
+    uint8_t digest[16] = {0};
2309
+    char *dstr;
2310
+    int i, err, ret = CL_SUCCESS, num_imports = 0, first = 1;
2311
+
2312
+    if (datadir->VirtualAddress == 0 || datadir->Size == 0) {
2313
+        cli_dbgmsg("IMPTBL: import table data directory does not exist\n");
2314
+        return CL_SUCCESS;
2315
+    }
2316
+
2317
+    impoff = cli_rawaddr(datadir->VirtualAddress, exe_sections, nsections, &err, fsize, hdr_size);
2318
+    if (err || impoff + datadir->Size > fsize) {
2319
+        cli_dbgmsg("IMPTBL: invalid rva for import table data\n");
2320
+        return CL_SUCCESS;
2321
+    }
2322
+
2323
+    impdes = fmap_need_off(map, impoff, datadir->Size);
2324
+    if (impdes == NULL) {
2325
+        cli_dbgmsg("IMPTBL: failed to acquire fmap buffer\n");
2326
+        return CL_SUCCESS; /* real error: CL_EMAP? */
2327
+    }
2328
+    left = datadir->Size;
2329
+
2330
+    md5ctx = cl_hash_init("md5");
2331
+    if (md5ctx == NULL)
2332
+        return CL_EMEM;
2333
+
2334
+    image = (struct pe_image_import_descriptor *)impdes;
2335
+    while(image->Name != 0 && num_imports < PE_MAXIMPORTS && left > sizeof(struct pe_image_import_descriptor)) {
2336
+        char *dllname = NULL;
2337
+
2338
+        left -= sizeof(struct pe_image_import_descriptor);
2339
+        num_imports++;
2340
+
2341
+        /* DLL name aquisition */
2342
+        offset = cli_rawaddr(image->Name, exe_sections, nsections, &err, fsize, hdr_size);
2343
+        if (err || offset > fsize) {
2344
+            cli_dbgmsg("IMPTBL: invalid rva for dll name\n");
2345
+            /* ignore or return? */
2346
+            /*
2347
+              image++;
2348
+              continue;
2349
+             */
2350
+            cl_hash_destroy(md5ctx);
2351
+            return CL_SUCCESS; /* error value? continue? */
2352
+        }
2353
+
2354
+        if ((buffer = fmap_need_off_once(map, offset, MIN(PE_MAXNAMESIZE, fsize-offset))) != NULL) {
2355
+            /* sanitize dllname? */
2356
+            dllname = strndup(buffer, MIN(PE_MAXNAMESIZE, fsize-offset));
2357
+            if (dllname == NULL) {
2358
+                cli_dbgmsg("IMPTBL: cannot duplicate dll name\n");
2359
+                cl_hash_destroy(md5ctx);
2360
+                return CL_EMEM;
2361
+            }
2362
+
2363
+            //cli_dbgmsg("IMPTBL: DLL: %s\n", dllname);
2364
+            /* JSON TOMFOOLERY */
2365
+        }
2366
+
2367
+        /* DLL function handling - inline function */
2368
+        ret = scan_pe_impfuncs(ctx, md5ctx, image, dllname, exe_sections, nsections, hdr_size, pe_plus, &first);
2369
+        if (dllname)
2370
+            free(dllname);
2371
+        if (ret != CL_SUCCESS) {
2372
+            cl_hash_destroy(md5ctx);
2373
+            return ret;
2374
+        }
2375
+
2376
+        image++;
2377
+    }
2378
+
2379
+    fmap_unneed_off(map, impoff, datadir->Size);
2380
+
2381
+    /* send off for md5 comparison - use ret */
2382
+    cl_finish_hash(md5ctx, digest);
2383
+    dstr = cli_str2hex(digest, sizeof(digest));
2384
+    cli_errmsg("IMPHASH: %s\n", (char *)dstr);
2385
+    free(dstr);
2386
+    return ret;
2387
+}
2388
+
557 2389
 #if HAVE_JSON
558 2390
 static struct json_object *get_pe_property(cli_ctx *ctx)
559 2391
 {
... ...
@@ -1461,6 +3330,23 @@ int cli_scanpe(cli_ctx *ctx)
1461 1461
             return ret == CL_VIRUS ? CL_VIRUS : CL_CLEAN;
1462 1462
     }
1463 1463
     cli_bytecode_context_destroy(bc_ctx);
1464
+
1465
+    /* Attempt to run scans on import table */
1466
+    /* TODO: should this be target-tree-only? */
1467
+    ret = scan_pe_imptbl(ctx, dirs, exe_sections, nsections, hdr_size, pe_plus);
1468
+    switch (ret) {
1469
+        case CL_ENULLARG:
1470
+            cli_warnmsg("cli_scanpe: NULL argument supplied\n");
1471
+            break;
1472
+        case CL_VIRUS:
1473
+            if (SCAN_ALL)
1474
+                break;
1475
+            /* intentional fall-through */
1476
+        case CL_BREAK:
1477
+            free(exe_sections);
1478
+            cli_bytecode_context_destroy(bc_ctx);
1479
+            return ret == CL_VIRUS ? CL_VIRUS : CL_CLEAN;
1480
+    }
1464 1481
     /* Attempt to detect some popular polymorphic viruses */
1465 1482
 
1466 1483
     /* W32.Parite.B */