sigtool/vba.c
9d0b7ebd
 /*
  *  Copyright (C) 2004 Trog <trog@uncon.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
48b7b4a7
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  *  MA 02110-1301, USA.
9d0b7ebd
  */
 
be4bf7f4
 #if HAVE_CONFIG_H
 #include "clamav-config.h"
 #endif
 
9d0b7ebd
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
8f5bb092
 #ifdef HAVE_UNISTD_H
9d0b7ebd
 #include <unistd.h>
8f5bb092
 #endif
9d0b7ebd
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <dirent.h>
 #include <ctype.h>
 
e48dcea9
 #include "libclamav/clamav.h"
 #include "libclamav/vba_extract.h"
 #include "libclamav/ole2_extract.h"
697bfad4
 #include "libclamav/readdb.h"
b705e8d7
 #include "shared/output.h"
9d0b7ebd
 
0735b685
 #include "vba.h"
 
288057e9
 typedef struct mac_token_tag {
9d0b7ebd
     unsigned char token;
797c5b1e
     const char *str;
9d0b7ebd
 } mac_token_t;
 
288057e9
 typedef struct mac_token2_tag {
9d0b7ebd
     uint16_t token;
797c5b1e
     const char *str;
9d0b7ebd
 
 } mac_token2_t;
 
288057e9
 cli_ctx *convenience_ctx(int fd)
 {
697bfad4
     cl_error_t status        = CL_EMEM;
     cli_ctx *ctx             = NULL;
     struct cl_engine *engine = NULL;
 
     /* build engine */
     engine = cl_engine_new();
     if (NULL == engine) {
         printf("convenience_ctx: engine initialization failed\n");
         goto done;
     }
 
     cl_engine_set_num(engine, CL_ENGINE_AC_ONLY, 1);
 
     if (cli_initroots(engine, 0) != CL_SUCCESS) {
         printf("convenience_ctx: cli_initroots() failed\n");
         goto done;
     }
8028d34f
 
697bfad4
     if (cli_parse_add(engine->root[0], "test", "deadbeef", 0, 0, 0, "*", 0, NULL, 0) != CL_SUCCESS) {
         printf("convenience_ctx: Can't parse signature\n");
         goto done;
     }
 
     if (CL_SUCCESS != cl_engine_compile(engine)) {
         printf("convenience_ctx: failed to compile engine.");
         goto done;
     }
 
     /* prepare context */
2283657c
     ctx = cli_calloc(1, sizeof(cli_ctx));
288057e9
     if (!ctx) {
697bfad4
         printf("convenience_ctx: ctx allocation failed\n");
         goto done;
8028d34f
     }
 
697bfad4
     ctx->engine = (const struct cl_engine *)engine;
 
     ctx->containers = cli_calloc(sizeof(cli_ctx_container), ctx->engine->maxreclevel + 2);
     if (NULL == ctx->containers) {
         printf("convenience_ctx: failed to allocate ctx containers.");
         goto done;
288057e9
     }
697bfad4
     ctx->containers[0].type = CL_TYPE_ANY;
 
     ctx->dconf = (struct cli_dconf *)engine->dconf;
8028d34f
 
697bfad4
     ctx->fmap = cli_calloc(sizeof(fmap_t *), ctx->engine->maxreclevel + 2);
288057e9
     if (!(ctx->fmap)) {
697bfad4
         printf("convenience_ctx: fmap initialization failed\n");
         goto done;
     }
 
     ctx->options = cli_calloc(1, sizeof(struct cl_scan_options));
     if (!ctx->options) {
         printf("convenience_ctx: scan options allocation failed\n");
         goto done;
8028d34f
     }
697bfad4
     ctx->options->general |= CL_SCAN_GENERAL_HEURISTICS;
     ctx->options->parse = ~(0);
8028d34f
 
288057e9
     if (!(*ctx->fmap = fmap(fd, 0, 0))) {
697bfad4
         printf("convenience_ctx: fmap failed\n");
         goto done;
3ef137af
     }
697bfad4
 
     status = CL_SUCCESS;
 
 done:
     if (CL_SUCCESS != status) {
         if (NULL != ctx) {
             if (NULL != ctx->fmap) {
                 free(ctx->fmap);
             }
             if (NULL != ctx->options) {
                 free(ctx->options);
             }
             if (NULL != ctx->containers) {
                 free(ctx->containers);
             }
             free(ctx);
             ctx = NULL;
         }
         if (NULL != engine) {
             cl_engine_free(engine);
         }
     }
 
3ef137af
     return ctx;
 }
 
288057e9
 void destroy_ctx(int desc, cli_ctx *ctx)
 {
e0f667e7
     if (desc >= 0)
         close(desc);
697bfad4
 
     if (NULL != ctx) {
         if (NULL != ctx->fmap) {
4f98a15b
             if (NULL != *(ctx->fmap)) {
                 funmap(*(ctx->fmap));
                 *(ctx->fmap) = NULL;
             }
 
697bfad4
             free(ctx->fmap);
             ctx->fmap = NULL;
         }
         if (NULL != ctx->engine) {
             cl_engine_free((struct cl_engine *)ctx->engine);
             ctx->engine = NULL;
         }
         if (NULL != ctx->options) {
             free(ctx->options);
             ctx->options = NULL;
         }
         if (NULL != ctx->containers) {
             free(ctx->containers);
             ctx->containers = NULL;
         }
         free(ctx);
     }
3ef137af
 }
 
72ce4b70
 int sigtool_vba_scandir(const char *dirname, int hex_output, struct uniq *U);
6a31c2b4
 
288057e9
 static char *get_unicode_name(char *name, int size)
9d0b7ebd
 {
     int i, j;
     char *newname;
 
     if (*name == 0 || size <= 0) {
288057e9
         return NULL;
9d0b7ebd
     }
 
288057e9
     newname = (char *)malloc(size * 2);
9d0b7ebd
     if (!newname) {
288057e9
         return NULL;
9d0b7ebd
     }
     j = 0;
     for (i = 0; i < size; i = i + 2) {
288057e9
         if (isprint(name[i])) {
             newname[j++] = name[i];
         } else {
             if (name[i] < 10 && name[i] >= 0) {
                 newname[j++] = '_';
                 newname[j++] = name[i] + '0';
             }
             newname[j++] = '_';
         }
9d0b7ebd
     }
     newname[j] = '\0';
     return newname;
 }
 
288057e9
 static void output_token(unsigned char token)
9d0b7ebd
 {
     int i;
     mac_token_t mac_token[] = {
288057e9
         {0x01, "-"},
         {0x02, "Not"},
         {0x03, "And"},
         {0x04, "Or"},
         {0x05, "("},
         {0x06, ")"},
         {0x07, "+"},
         {0x08, "-"},
         {0x09, "/"},
         {0x0a, "*"},
         {0x0b, "Mod"},
         {0x0c, "="},
         {0x0d, "<>"},
         {0x0e, "<"},
         {0x0f, ">"},
         {0x10, "<="},
         {0x11, ">="},
         {0x12, ","},
         {0x18, "Resume"},
         {0x19, ":"},
         {0x1a, "End"},
         {0x1b, "Sub"},
         {0x1c, "Function"},
         {0x1d, "If"},
         {0x1e, "Then"},
         {0x1f, "ElseIf"},
         {0x20, "Else"},
         {0x21, "While"},
         {0x22, "Wend"},
         {0x23, "For"},
         {0x24, "To"},
         {0x25, "Step"},
         {0x26, "Next"},
         {0x28, ";"},
         {0x29, "Call"},
         {0x2a, "Goto"},
         {0x2c, "On"},
         {0x2d, "Error"},
         {0x2e, "Let"},
         {0x2f, "Dim"},
         {0x30, "Shared"},
         {0x31, "Select"},
         {0x32, "Is"},
         {0x33, "Case"},
         {0x34, "As"},
         {0x35, "Redim"},
         {0x36, "Print"},
         {0x37, "Input"},
         {0x38, "Line"},
         {0x39, "Write"},
         {0x3a, "Name"},
         {0x3b, "Output"},
         {0x3c, "Append"},
         {0x3d, "Open"},
         {0x3e, "GetCurValues"},
         {0x3f, "Dialog"},
         {0x40, "Super"},
         {0x41, "Declare"},
         {0x42, "Double"},
         {0x43, "Integer"},
         {0x44, "Long"},
         {0x45, "Single"},
         {0x46, "String"},
         {0x47, "Cdecl"},
         {0x48, "Alias"},
         {0x49, "Any"},
         {0x4a, "ToolsGetSpelling"},
         {0x4b, "ToolsGetSynonyms"},
         {0x4c, "Close"},
         {0x4d, "Begin"},
         {0x4e, "Lib"},
         {0x4f, "Read"},
         {0x50, "CheckDialog"},
         {0x51, " "}, /* not sure about this one - some white space */
         {0x52, "\t"},
         {0x54, "EndIf"},
         {0x64, "\n"},
         {0x71, "#"},
         {0x72, "\\"},
         {0x00, NULL},
9d0b7ebd
     };
 
     for (i = 0; mac_token[i].token != 0x00; i++) {
288057e9
         if (token == mac_token[i].token) {
             printf(" %s ", mac_token[i].str);
             return;
         }
9d0b7ebd
     }
288057e9
     printf("[#0x%x]", token);
9d0b7ebd
     return;
 }
 
288057e9
 static void output_token67(uint16_t token)
9d0b7ebd
 {
     int i;
     mac_token2_t mac_token[] = {
288057e9
         {0x0004, "HelpActivateWindow"},
         {0x0009, "HelpAbout"},
         {0x000c, "ShrinkFont"},
         {0x0016, "NextWindow"},
         {0x0017, "PrevWindow"},
         {0x001c, "DeleteWord"},
         {0x001e, "EditClear"},
         {0x0045, "GoBack"},
         {0x0046, "SaveTemplate"},
         {0x0048, "Cancel"},
         {0x004e, "DocumentStatistics"},
         {0x004f, "FileNew"},
         {0x0050, "FileOpen"},
         {0x0053, "FileSave"},
         {0x0054, "FileSaveAs"},
         {0x0056, "FileSummaryInfo"},
         {0x0057, "FileTemplates"},
         {0x0058, "FilePrint"},
         {0x0061, "FilePrintSetup"},
         {0x0063, "FileFind"},
         {0x006c, "EditCut"},
         {0x006d, "EditCopy"},
         {0x006e, "EditPaste"},
         {0x0070, "EditFind"},
         {0x0074, "EditFindClearFormatting"},
         {0x0075, "EditReplace"},
         {0x0079, "EditReplaceClearFormatting"},
         {0x007a, "EditGoTo"},
         {0x007b, "EditAutoText"},
         {0x0093, "ViewPage"},
         {0x0098, "ToolsCustomize"},
         {0x009b, "NormalViewHeaderArea"},
         {0x009f, "InsertBreak"},
         {0x00a2, "InsertSymbol"},
         {0x00a4, "InsertFile"},
         {0x00a8, "EditBookmark"},
         {0x00ac, "InsertObject"},
         {0x00ae, "FormatFont"},
         {0x00af, "FormatParagraph"},
         {0x00b2, "FilePageSetup"},
         {0x00bf, "ToolsSpelling"},
         {0x00ca, "ToolsOptions"},
         {0x00cc, "ToolsOptionsView"},
         {0x00cb, "ToolsOptionsGeneral"},
         {0x00d1, "ToolsOptionsSave"},
         {0x00d3, "ToolsOptionsSpelling"},
         {0x00d5, "ToolsOptionsUserInfo"},
         {0x00d7, "ToolsMacro"},
         {0x00de, "Organizer"},
         {0x00e1, "ToolsOptionsFileLocations"},
         {0x00e4, "ToolsWordCount"},
         {0x00e9, "DocRestore"},
         {0x00ed, "EditSelectAll"},
         {0x00f3, "ClosePane"},
         {0x0129, "UserDialog"},
         {0x012c, "CopyFile"},
         {0x012d, "FileNewDefault"},
         {0x012e, "FilePrintDefault"},
         {0x0143, "ViewToolbars"},
         {0x015d, "TextFormField"},
         {0x0161, "FormFieldOptions"},
         {0x0172, "InsertFootnote"},
         {0x0179, "DrawRectangle"},
         {0x017a, "ToolsAutoCorrect"},
         {0x01a4, "Connect"},
         {0x01a5, "WW2_EditFind"},
         {0x01a6, "WW2_EditReplace"},
         {0x01b0, "ToolsCustomizeKeyboard"},
         {0x01b1, "ToolsCustomizeMenus"},
         {0x01d2, "DrawBringToFront"},
         {0x01d3, "DrawSendToBack"},
         {0x01e3, "InsertFormField"},
         {0x01f7, "ToolsProtectDocument"},
         {0x0202, "ShrinkFontOnePoint"},
         {0x0209, "ToolsUnprotectDocument"},
         {0x022f, "DrawFlipHorizontal"},
         {0x0235, "FormatDrawingObject"},
         {0x0241, "ViewZoom"},
         {0x0246, "ToogleFull"},
         {0x024a, "NewToolbar"},
         {0x0265, "FileSendMail"},
         {0x0267, "ToolsCustomizeMenuBar"},
         {0x0270, "FileRoutingSlip"},
         {0x0273, "ChooseButtonImage"},
         {0x027b, "HelpTipOfTheDay"},
         {0x0280, "Int"},
         {0x0290, "MicrosoftMail"},
         {0x0299, "ScreenRefresh"},
         {0x02b0, "HelpContents"},
         {0x0780, "Str$"},
         {0x0e80, "Rnd"},
         {0x2580, "FileName$"},
         {0x2b80, "MsgBox"},
         {0x2c80, "Beep"},
         {0x5400, "FileSaveAs"},
         {0x5600, "FileSummaryInfo"},
         {0x8000, "Abs"},
         {0x8001, "Sgn"},
         {0x8002, "Int"},
         {0x8003, "Len"},
         {0x8004, "Asc"},
         {0x8005, "Chr$"},
         {0x8006, "Val"},
         {0x8007, "Str$"},
         {0x8008, "Left$"},
         {0x8009, "Right$"},
         {0x800a, "Mid$"},
         {0x800b, "String$"},
         {0x800c, "Date$"},
         {0x800d, "Time$"},
         {0x800e, "Rnd"},
         {0x800f, "InStr"},
         {0x8012, "Insert"},
         {0x8013, "InsertPara"},
         {0x8015, "Selection$"},
         {0x801b, "ExistingBookMark"},
         {0x8023, "IsDocumentDirty"},
         {0x8024, "SetDocumentDirty"},
         {0x8025, "FileName$"},
         {0x8026, "CountFiles"},
         {0x8027, "GetAutoText$"},
         {0x8028, "CountAutoTextEntries"},
         {0x802a, "SetAutoText"},
         {0x802b, "MsgBox"},
         {0x802c, "Beep"},
         {0x802d, "Shell"},
         {0x802f, "ResetPara"},
         {0x8032, "DocMove"},
         {0x8033, "DocSize"},
         {0x8034, "VLine"},
         {0x803a, "CountWindows"},
         {0x803b, "WindowName$"},
         {0x803e, "Window"},
         {0x8041, "AppMinimize"},
         {0x8042, "AppMaximize"},
         {0x8043, "AppRestore"},
         {0x8044, "DocMaximize"},
         {0x8045, "GetProfileString$"},
         {0x8046, "SetProfileString"},
         {0x8047, "CharColor"},
         {0x8048, "Bold"},
         {0x8049, "Italic"},
         {0x804e, "UnderLine"},
         {0x8053, "CenterPara"},
         {0x8054, "LeftPara"},
         {0x8055, "RightPara"},
         {0x8056, "JustifyPara"},
         {0x805c, "DDEInitiate"},
         {0x805d, "DDETerminate"},
         {0x8053, "DDETerminateAll"},
         {0x805f, "DDEExecute"},
         {0x8060, "DDEPoke"},
         {0x8061, "DDERequest$"},
         {0x8062, "Activate"},
         {0x8063, "AppActivate"},
         {0x8064, "SendKeys"},
         {0x806f, "ViewStatusBar"},
         {0x8071, "ViewRibbon"},
         {0x8073, "ViewPage"},
         {0x8075, "ViewNormal"},
         {0x8079, "Overtype"},
         {0x807a, "Font$"},
         {0x807b, "CountOfFonts"},
         {0x807c, "Font"},
         {0x807d, "FontSize"},
         {0x8081, "WW6_EditClear"},
         {0x8082, "FileList"},
         {0x8083, "File1"},
         {0x8098, "ExtendSelection"},
         {0x809e, "DisableInput"},
         {0x809f, "DocClose"},
         {0x80a0, "FileClose"},
         {0x80a1, "File$"},
         {0x80a2, "FileExit"},
         {0x80a3, "FileSaveAll"},
         {0x80a7, "Input$"},
         {0x80a8, "Seek"},
         {0x80a9, "Eof"},
         {0x80aa, "Lof"},
         {0x80ab, "Kill"},
         {0x80ac, "ChDir"},
         {0x80ad, "MkDir"},
         {0x80ae, "RmDir"},
         {0x80af, "UCase$"},
         {0x80b0, "LCase$"},
         {0x80b1, "InoutBox$"},
         {0x80b3, "OnTime"},
         {0x80b5, "AppInfo$"},
         {0x80b6, "SelInfo"},
         {0x80b7, "CountMacros"},
         {0x80b8, "MacroName"},
         {0x80b9, "CountFoundFiles"},
         {0x80ba, "FoundFileName$"},
         {0x80be, "MacroDesc$"},
         {0x80bf, "CountKeys"},
         {0x80c1, "KeyMacro$"},
         {0x80c2, "MacroCopy"},
         {0x80c3, "IsExecuteOnly"},
         {0x80c7, "OKButton"},
         {0x80c8, "CancelButton"},
         {0x80c9, "Text"},
         {0x80ca, "GroupBox"},
         {0x80cb, "OptionButton"},
         {0x80cc, "PushButton"},
         {0x80d5, "ExitWindows"},
         {0x80d6, "DisableAutoMacros"},
         {0x80d7, "EditFindFound"},
         {0x80d8, "CheckBox"},
         {0x80d9, "TextBox"},
         {0x80da, "ListBox"},
         {0x80db, "OptionGroup"},
         {0x80dc, "ComboBox"},
         {0x80de, "WindowList"},
         {0x80e8, "CountDirectories"},
         {0x80e9, "GetDirectory$"},
         {0x80ea, "LTrim$"},
         {0x80eb, "RTrim$"},
         {0x80ee, "Environ$"},
         {0x80ef, "WaitCursor"},
         {0x80f0, "DateSerial"},
         {0x80f1, "DateValue"},
         {0x80f2, "Day"},
         {0x80f4, "Hour"},
         {0x80f5, "Minute"},
         {0x80f6, "Month"},
         {0x80f7, "Now"},
         {0x80f8, "WeekdayNow"},
         {0x80f9, "Year"},
         {0x80fa, "DocWindowHeight"},
         {0x80fb, "DocWindowWidth"},
         {0x80fc, "DOSToWIN$"},
         {0x80fd, "WinToDOS$"},
         {0x80ff, "Second"},
         {0x8100, "TimeValue"},
         {0x8101, "Today"},
         {0x8103, "SetAttr"},
         {0x8105, "DocMinimize"},
         {0x8107, "AppActivate"},
         {0x8108, "AppCount"},
         {0x8109, "AppGetNames"},
         {0x810a, "AppHide"},
         {0x810b, "AppIsRunning"},
         {0x810c, "GetSystemInfo$"},
         {0x810d, "GetPrivateProfileString$"},
         {0x810e, "SetPrivateProfileString"},
         {0x810f, "GetAttr"},
         {0x8111, "ScreenUpdating"},
         {0x8116, "SelectCurWord"},
         {0x8118, "IsTemplateDirty"},
         {0x8119, "SetTemplateDirty"},
         {0x811b, "DlgEnable"},
         {0x811d, "DlgVisible"},
         {0x811f, "DlgText$"},
         {0x8121, "AppShow"},
         {0x8122, "DlgListBoxArray"},
         {0x8125, "Picture"},
         {0x8126, "DlgSetPicture"},
         {0x8131, "WW2_Files$"},
         {0x8138, "DlgFocus"},
         {0x813b, "BorderLineStyle"},
         {0x813d, "MenuItemText$"},
         {0x813e, "MenuItemMacro$"},
         {0x813f, "CountMenus"},
         {0x8140, "MenuText$"},
         {0x8141, "CountMenuItems"},
         {0x8145, "DocWindowPosTop"},
         {0x8146, "DocWindowPosLeft"},
         {0x8147, "Stop"},
         {0x8148, "DropListBox"},
         {0x8149, "RenameMenu"},
         {0x814a, "FileCloseAll"},
         {0x814b, "SortArray"},
         {0x814c, "SetDocumentVar"},
         {0x814d, "GetDocumentVar$"},
         {0x8152, "IsMacro"},
         {0x8153, "FileNameFromWindow$"},
         {0x815b, "MoveToolbar"},
         {0x816e, "MacID$"},
         {0x8170, "GetSelEndPos"},
         {0x8171, "SetSelRange"},
         {0x8172, "GetText$"},
         {0x8174, "DeleteButton"},
         {0x8175, "AddButton"},
         {0x8177, "DeleteAddIn"},
         {0x8178, "AddAddIn"},
         {0x8179, "GetAddInName$"},
         {0x817c, "ResetButtonImage"},
         {0x8180, "GetAddInId"},
         {0x8181, "CountAddIns"},
         {0x8182, "ClearAddIns"},
         {0x8183, "AddInState"},
         {0x818c, "DefaultDir$"},
         {0x818d, "FileNameInfo$"},
         {0x818e, "MacroFileName$"},
         {0x818f, "ViewHeader"},
         {0x8190, "ViewFooter"},
         {0x8192, "CopyButtonImage"},
         {0x8195, "CountToolbars"},
         {0x8196, "ToolbarName$"},
         {0x8198, "ChDefaultDir"},
         {0x8199, "EditUndo"},
         {0x81a0, "GetAutoCorrect$"},
         {0x81a2, "FileQuit"},
         {0x81a4, "FileConfirmConversions"},
         {0x81d3, "SelectionFileName$"},
         {0x81d9, "CountToolbarButtons"},
         {0x81da, "ToolbarButtonMacro$"},
         {0x81db, "WW2_Insert"},
         {0x81dc, "AtEndOfDocument"},
         {0x81fc, "GetDocumentProperty$"},
         {0x81fd, "GetDocumentProperty"},
         {0x8201, "DocumentPropertyName$"},
         {0x820e, "SpellChecked"},
         {0xb780, "CountMacros"},
         {0xb880, "MacroName$"},
         {0xc000, "CharLeft"},
         {0xc001, "CharRight"},
         {0xc002, "WordLeft"},
         {0xc003, "WordRight"},
         {0xc004, "EndOfLine"},
         {0xc007, "ParaDown"},
         {0xc008, "LineUp"},
         {0xc009, "LineDown"},
         {0xc00a, "PageUp"},
         {0xc00c, "StartOfLine"},
         {0xc00d, "EndOfLine"},
         {0xc010, "StartOfDocument"},
         {0xc011, "EndOfDocument"},
         {0xc012, "EditClear"},
         {0xc024, "BorderTop"},
         {0xc025, "BorderLeft"},
         {0xc026, "BorderBottom"},
         {0xc027, "BorderRight"},
         {0xc280, "MacroCopy"},
         {0x0000, NULL},
9d0b7ebd
     };
     for (i = 0; mac_token[i].token != 0x0000; i++) {
288057e9
         if (token == mac_token[i].token) {
             printf("%s", mac_token[i].str);
             return;
         }
9d0b7ebd
     }
288057e9
     printf("[#67(0x%x)]", token);
9d0b7ebd
     return;
 }
 
288057e9
 static void output_token73(uint16_t token)
9d0b7ebd
 {
     int i;
     mac_token2_t mac_token[] = {
288057e9
         {0x0001, ".Name"},
         {0x0002, ".KeyCode"},
         {0x0003, ".Context"},
         {0x0004, ".ResetAll"},
         {0x0007, ".Menu"},
         {0x0008, ".MenuText"},
         {0x0009, ".APPUSERNAME"},
         {0x000b, ".Delete"},
         {0x000c, ".Sort"},
         {0x0012, ".SavedBy"},
         {0x0014, ".DateCreatedFrom"},
         {0x0015, ".DateCreatedTo"},
         {0x0016, ".DateSavedFrom"},
         {0x0017, ".DateSavedTo"},
         {0x0020, ".ButtonFieldClicks"},
         {0x0021, ".Font"},
         {0x0022, ".Points"},
         {0x0023, ".Color"},
         {0x0024, ".Bold"},
         {0x0025, ".Italic"},
         {0x0027, ".Hidden"},
         {0x0028, ".Underline"},
         {0x0029, ".Outline"},
         {0x002b, ".Position"},
         {0x002d, ".Spacing"},
         {0x002f, ".Printer"},
         {0x0034, ".AutoSave"},
         {0x0035, ".Units"},
         {0x0036, ".Pagination"},
         {0x0037, ".SummaryPrompt"},
         {0x0039, ".Initials"},
         {0x003a, ".Tabs"},
         {0x003b, ".Spaces"},
         {0x003c, ".Paras"},
         {0x003d, ".Hyphens"},
         {0x003e, ".ShowAll"},
         {0x0041, ".TextBoundaries"},
         {0x0043, ".VScroll"},
         {0x0046, ".PageWidth"},
         {0x0047, ".PageHeight"},
         {0x0049, ".TopMargin"},
         {0x004a, ".BottomMargin"},
         {0x004b, ".LeftMargin"},
         {0x004c, ".RightMargin"},
         {0x0052, ".Template"},
         {0x0059, ".RecentFileCount"},
         {0x005d, ".SmallCaps"},
         {0x0060, ".Password"},
         {0x0061, ".RecentFiles"},
         {0x0062, ".Title"},
         {0x0063, ".Subject"},
         {0x0064, ".Author"},
         {0x0065, ".Keywords"},
         {0x0066, ".Comments"},
         {0x0067, ".FileName"},
         {0x0068, ".Directory"},
         {0x0069, ".CreateDate"},
         {0x006a, ".LastSavedDate"},
         {0x006b, ".LastSavedBy"},
         {0x006c, ".RevisionNumber"},
         {0x006f, ".NumPages"},
         {0x0070, ".NumWords"},
         {0x0071, ".NumChars"},
         {0x0074, ".Rename"},
         {0x0075, ".NewName"},
         {0x0078, ".SmartQuotes"},
         {0x007f, ".Source"},
         {0x0080, ".Reference"},
         {0x0085, ".Insert"},
         {0x0086, ".Destination"},
         {0x0087, ".Type"},
         {0x0089, ".HeaderDistance"},
         {0x008a, ".FooterDistance"},
         {0x008b, ".FirstPage"},
         {0x008c, ".OddAndEvenPages"},
         {0x0091, ".Entry"},
         {0x0092, ".Range"},
         {0x0095, ".Link"},
         {0x0098, ".Add"},
         {0x009b, ".NewTemplate"},
         {0x009f, ".ReadOnly"},
         {0x00a1, ".LeftIndent"},
         {0x00a2, ".RightIndent"},
         {0x00a3, ".FirstIndent"},
         {0x00a5, ".After"},
         {0x00b9, ".NumCopies"},
         {0x00ba, ".From"},
         {0x00bb, ".To"},
         {0x00cb, ".Format"},
         {0x00cd, ".Replace"},
         {0x00ce, ".WholeWord"},
         {0x00cf, ".MatchCase"},
         {0x00d7, ".CreateBackup"},
         {0x00d8, ".LockAnnot"},
         {0x00d9, ".Direction"},
         {0x00ff, ".SuggestFromMainDictOnly"},
         {0x012b, ".UpdateLinks"},
         {0x012e, ".Update"},
         {0x0131, ".Text"},
         {0x0136, ".Description"},
         {0x0139, ".Setting"},
         {0x013b, ".AllCaps"},
         {0x0148, ".Category"},
         {0x0149, ".ConfirmConversions"},
         {0x014c, ".StatusBar"},
         {0x014d, ".PicturePlaceHolders"},
         {0x014e, ".FieldCodes"},
         {0x0150, ".Show"},
         {0x0156, ".FastSaves"},
         {0x0157, ".SaveInterval"},
         {0x0161, ".LineColor"},
         {0x017d, ".Wrap"},
         {0x0183, ".AutoFit"},
         {0x0184, ".CharNum"},
         {0x018b, ".View"},
         {0x0190, ".Options"},
         {0x0194, ".Find"},
         {0x0196, ".Path"},
         {0x01a8, ".Background"},
         {0x01a9, ".SearchPath"},
         {0x01ab, ".CustomDict1"},
         {0x01ac, ".CustomDict2"},
         {0x01ad, ".CustomDict3"},
         {0x01ae, ".CustomDict4"},
         {0x01b1, ".Collate"},
         {0x01b2, ".Shadow"},
         {0x01b4, ".Button"},
         {0x01b9, ".Remove"},
         {0x01ba, ".Protect"},
         {0x01d7, ".Store"},
         {0x01da, ".Class"},
         {0x01de, ".Hide"},
         {0x01df, ".Toolbar"},
         {0x01e0, ".ReplaceAll"},
         {0x01eb, ".Address"},
         {0x01f4, ".SelectedFile"},
         {0x01f5, ".Run"},
         {0x01f6, ".Edit"},
         {0x0218, ".LastSaved"},
         {0x0219, ".Revision"},
         {0x021c, ".Pages"},
         {0x021d, ".Words"},
         {0x0232, ".WPHelp"},
         {0x0233, ".WPDocNavKeys"},
         {0x0234, ".SetDesc"},
         {0x023d, ".CountFootNodes"},
         {0x0255, ".AddToMru"},
         {0x0262, ".NoteTypes"},
         {0x0272, ".With"},
         {0x0275, ".CustoDict5"},
         {0x0276, ".CustoDict6"},
         {0x0277, ".CustoDict7"},
         {0x0278, ".CustoDict8"},
         {0x0279, ".CustoDict9"},
         {0x027a, ".CustoDict10"},
         {0x027e, ".ErrorBeeps"},
         {0x0285, ".Goto"},
         {0x0287, ".Copy"},
         {0x028e, ".Caption"},
         {0x0299, ".AddBelow"},
         {0x02a4, ".Effects3d"},
         {0x02ac, ".MenuType"},
         {0x02ad, ".DraftFont"},
         {0x02af, ".WrapToWindow"},
         {0x02b0, ".Drawings"},
         {0x02c0, ".NumLines"},
         {0x02c6, ".SuperScript"},
         {0x02c7, ".Subscript"},
         {0x02c8, ".WritePassword"},
         {0x02c9, ".RecommendReadOnly"},
         {0x02ca, ".DocumentPassword"},
         {0x02d5, ".HelpText"},
         {0x02d6, ".InsertAs"},
         {0x02dc, ".Formatting"},
         {0x02de, ".InitialCaps"},
         {0x02df, ".SentenceCaps"},
         {0x02e0, ".Days"},
         {0x02e1, ".ReplaceText"},
         {0x02e4, ".Product"},
         {0x02f1, ".SoundsLike"},
         {0x02f2, ".KerningMin"},
         {0x02f3, ".PatternMatch"},
         {0x0308, ".EmbedFonts"},
         {0x030a, ".Width"},
         {0x030b, ".Height"},
         {0x0316, ".SendMailAttach"},
         {0x0318, ".Kerning"},
         {0x0319, ".Exit"},
         {0x031a, ".Enable"},
         {0x031b, ".OwnHelp"},
         {0x031c, ".OwnStat"},
         {0x031d, ".StatText"},
         {0x031e, ".FormsData"},
         {0x0320, ".BookMarks"},
         {0x0327, ".LinkStyles"},
         {0x032a, ".Message"},
         {0x032d, ".AllAtOnce"},
         {0x032f, ".TrackStatus"},
         {0x0330, ".FillColor"},
         {0x0332, ".FillPatternColor"},
         {0x033a, ".RoundCorners"},
         {0x0349, ".TextType"},
         {0x0353, ".TextWidth"},
         {0x0354, ".TextDefault"},
         {0x0355, ".TextFormat"},
         {0x0366, ".SearchName"},
         {0x0370, ".BlueScreen"},
         {0x0377, ".ListBy"},
         {0x0378, ".SubDir"},
         {0x0388, ".HorizontalPos"},
         {0x0389, ".HorizontalFrom"},
         {0x038a, ".VerticalPos"},
         {0x038b, ".VerticalFrom"},
         {0x038f, ".Tab"},
         {0x039a, ".Strikethrough"},
         {0x039b, ".Face"},
         {0x039d, ".NativePictureFormat"},
         {0x039e, ".FileSize"},
         {0x03a2, ".LineType"},
         {0x03a4, ".DisplayIcon"},
         {0x03a8, ".IconFilename"},
         {0x03a9, ".IconNumber"},
         {0x03ac, ".GlobalDotPrompt"},
         {0x03b2, ".NoReset"},
         {0x03db, ".SaveAsAOCELetter"},
         {0x041b, ".CapsLock"},
         {0x0422, ".FindAllWordForms"},
         {0x045e, ".VirusProtection"},
         {0x6200, ".Title"},
         {0x6300, ".Subject"},
         {0x6400, ".Author"},
         {0x6500, ".Keywords"},
         {0x6600, ".Comments"},
         {0xcb00, ".Format"},
         {0x0000, NULL},
9d0b7ebd
     };
 
     for (i = 0; mac_token[i].token != 0x0000; i++) {
288057e9
         if (token == mac_token[i].token) {
             printf("%s", mac_token[i].str);
             return;
         }
9d0b7ebd
     }
288057e9
     printf("[#73(0x%x)]", token);
9d0b7ebd
     return;
 }
 
288057e9
 static void print_hex_buff(unsigned char *start, unsigned char *end, int hex_output)
9d0b7ebd
 {
     if (!hex_output) {
288057e9
         return;
9d0b7ebd
     }
288057e9
     printf("[clam hex:");
9d0b7ebd
     while (start < end) {
288057e9
         printf(" %.2x", *start);
         start++;
9d0b7ebd
     }
288057e9
     printf("]\n");
9d0b7ebd
 }
 
7959343d
 #ifdef __GNUC__
288057e9
 static void wm_decode_macro(unsigned char *buff, uint32_t len, int hex_output) __attribute__((unused));
7959343d
 #endif
288057e9
 static void wm_decode_macro(unsigned char *buff, uint32_t len, int hex_output)
9d0b7ebd
 {
797c5b1e
     uint32_t i;
     uint8_t s_length, j;
9d0b7ebd
     uint16_t w_length, int_val;
     unsigned char *tmp_buff, *tmp_name, *line_start;
 
288057e9
     i          = 2;
9d0b7ebd
     line_start = buff;
     while (i < len) {
288057e9
         switch (buff[i]) {
             case 0x65:
                 s_length = (uint8_t)buff[i + 1];
                 tmp_buff = (unsigned char *)malloc(s_length + 1);
                 strncpy((char *)tmp_buff, (char *)(buff + i + 2), s_length);
                 tmp_buff[s_length] = '\0';
                 print_hex_buff(line_start, buff + i + 2 + s_length, hex_output);
                 printf("\n%s", tmp_buff);
                 free(tmp_buff);
                 i += 2 + s_length;
                 line_start = buff + i;
                 break;
             case 0x69:
                 s_length = (uint8_t)buff[i + 1];
                 tmp_buff = (unsigned char *)malloc(s_length + 1);
                 strncpy((char *)tmp_buff, (char *)(buff + i + 2), s_length);
                 tmp_buff[s_length] = '\0';
                 printf(" %s", tmp_buff);
                 free(tmp_buff);
                 i += 2 + s_length;
                 break;
             case 0x6a:
                 s_length = (uint8_t)buff[i + 1];
                 tmp_buff = (unsigned char *)malloc(s_length + 1);
                 strncpy((char *)tmp_buff, (char *)(buff + i + 2), s_length);
                 tmp_buff[s_length] = '\0';
                 printf(" \"%s\"", tmp_buff);
                 free(tmp_buff);
                 i += 2 + s_length;
                 break;
             case 0x6b:
                 s_length = (uint8_t)buff[i + 1];
                 tmp_buff = (unsigned char *)malloc(s_length + 1);
                 strncpy((char *)tmp_buff, (char *)(buff + i + 2), s_length);
                 tmp_buff[s_length] = '\0';
                 printf(" '%s", tmp_buff);
                 free(tmp_buff);
                 i += 2 + s_length;
                 break;
             case 0x6d:
                 s_length = (uint8_t)buff[i + 1];
                 tmp_buff = (unsigned char *)malloc(s_length + 1);
                 strncpy((char *)tmp_buff, (char *)(buff + i + 2), s_length);
                 tmp_buff[s_length] = '\0';
                 printf(" %s", tmp_buff);
                 free(tmp_buff);
                 i += 2 + s_length;
                 break;
             case 0x70:
                 s_length = (uint8_t)buff[i + 1];
                 tmp_buff = (unsigned char *)malloc(s_length + 1);
                 strncpy((char *)tmp_buff, (char *)(buff + i + 2), s_length);
                 tmp_buff[s_length] = '\0';
                 printf("REM%s", tmp_buff);
                 free(tmp_buff);
                 i += 2 + s_length;
                 break;
             case 0x76:
                 s_length = (uint8_t)buff[i + 1];
                 tmp_buff = (unsigned char *)malloc(s_length + 1);
                 strncpy((char *)tmp_buff, (char *)(buff + i + 2), s_length);
                 tmp_buff[s_length] = '\0';
                 printf(" .%s", tmp_buff);
                 free(tmp_buff);
                 i += 2 + s_length;
                 break;
             case 0x77:
                 s_length = (uint8_t)buff[i + 1];
                 tmp_buff = (unsigned char *)malloc(s_length + 1);
                 strncpy((char *)tmp_buff, (char *)(buff + i + 2), s_length);
                 tmp_buff[s_length] = '\0';
                 printf("%s", tmp_buff);
                 free(tmp_buff);
                 i += 2 + s_length;
                 break;
             case 0x79: /* unicode "string" */
                 w_length = (uint16_t)(buff[i + 2] << 8) + buff[i + 1];
                 tmp_buff = (unsigned char *)malloc((w_length * 2) + 1);
                 memcpy(tmp_buff, buff + i + 3, w_length * 2);
                 tmp_name = (unsigned char *)get_unicode_name((char *)tmp_buff, w_length * 2);
                 free(tmp_buff);
                 printf("\"%s\"", tmp_name);
                 free(tmp_name);
                 i += 3 + (w_length * 2);
                 break;
9d0b7ebd
 
288057e9
             case 0x7c: /* unicode 'string */
                 s_length = (uint8_t)buff[i + 1];
                 tmp_buff = (unsigned char *)malloc((s_length * 2) + 1);
                 memcpy(tmp_buff, buff + i + 2, s_length * 2);
                 tmp_name = (unsigned char *)get_unicode_name((char *)tmp_buff, s_length * 2);
                 free(tmp_buff);
                 printf("'%s", tmp_name);
                 free(tmp_name);
                 i += 2 + (s_length * 2);
                 break;
9d0b7ebd
 
288057e9
             case 0x66:
                 int_val = (uint8_t)(buff[i + 2] << 8) + buff[i + 1];
                 print_hex_buff(line_start, buff + i + 3, hex_output);
                 printf("\n%d", int_val);
                 i += 3;
                 line_start = buff + i;
                 break;
             case 0x67:
                 w_length = (uint16_t)(buff[i + 2] << 8) + buff[i + 1];
                 output_token67(w_length);
                 i += 3;
                 break;
             case 0x68:
                 /* 8-byte float */
                 printf("(float)");
                 i += 9;
                 break;
             case 0x6c:
                 int_val = (uint16_t)(buff[i + 2] << 8) + buff[i + 1];
                 printf(" %d", int_val);
                 i += 3;
                 break;
             case 0x6e:
                 s_length = (uint8_t)buff[i + 1];
                 for (j = 0; j < s_length; j++) {
                     printf(" ");
                 }
                 i += 2;
                 break;
             case 0x6f:
                 s_length = (uint8_t)buff[i + 1];
                 for (j = 0; j < s_length; j++) {
                     printf("\t");
                 }
                 i += 2;
                 break;
             case 0x73:
                 w_length = (uint16_t)(buff[i + 2] << 8) + buff[i + 1];
                 output_token73(w_length);
                 i += 3;
                 break;
             case 0x64:
                 print_hex_buff(line_start, buff + i + 1, hex_output);
                 printf("\n");
                 i++;
                 line_start = buff + i;
                 break;
             default:
                 output_token(buff[i]);
                 i++;
                 break;
         }
9d0b7ebd
     }
288057e9
     print_hex_buff(line_start, buff + i, hex_output);
9d0b7ebd
 }
 
288057e9
 static int sigtool_scandir(const char *dirname, int hex_output)
9d0b7ebd
 {
     DIR *dd;
     struct dirent *dent;
a2a004df
     STATBUF statbuf;
9d0b7ebd
     char *fname;
     const char *tmpdir;
     char *dir;
6a31c2b4
     int ret = CL_CLEAN, desc;
3ef137af
     cli_ctx *ctx;
9d0b7ebd
 
0fdaab06
     fname = NULL;
288057e9
     if ((dd = opendir(dirname)) != NULL) {
         while ((dent = readdir(dd))) {
             if (dent->d_ino) {
                 if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
                     /* build the full name */
                     fname = (char *)cli_calloc(strlen(dirname) + strlen(dent->d_name) + 2, sizeof(char));
                     if (!fname) {
                         closedir(dd);
                         return -1;
                     }
                     sprintf(fname, "%s" PATHSEP "%s", dirname, dent->d_name);
9d0b7ebd
 
288057e9
                     /* stat the file */
                     if (LSTAT(fname, &statbuf) != -1) {
                         if (S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) {
                             if (sigtool_scandir(fname, hex_output)) {
                                 free(fname);
                                 closedir(dd);
                                 return CL_VIRUS;
                             }
                         } else {
                             if (S_ISREG(statbuf.st_mode)) {
                                 struct uniq *vba = NULL;
                                 tmpdir           = cli_gettmpdir();
799a761f
 
288057e9
                                 /* generate the temporary directory */
                                 dir = cli_gentemp(tmpdir);
                                 if (!dir) {
                                     printf("cli_gentemp() failed\n");
                                     free(fname);
                                     closedir(dd);
                                     return -1;
                                 }
9d0b7ebd
 
288057e9
                                 if (mkdir(dir, 0700)) {
                                     printf("Can't create temporary directory %s\n", dir);
                                     free(fname);
                                     closedir(dd);
                                     free(dir);
                                     return CL_ETMPDIR;
                                 }
9d0b7ebd
 
288057e9
                                 if ((desc = open(fname, O_RDONLY | O_BINARY)) == -1) {
                                     printf("Can't open file %s\n", fname);
                                     free(fname);
                                     closedir(dd);
                                     free(dir);
                                     return 1;
                                 }
9d0b7ebd
 
288057e9
                                 if (!(ctx = convenience_ctx(desc))) {
                                     free(fname);
                                     close(desc);
                                     closedir(dd);
                                     free(dir);
                                     return 1;
                                 }
                                 if ((ret = cli_ole2_extract(dir, ctx, &vba))) {
                                     printf("ERROR %s\n", cl_strerror(ret));
                                     destroy_ctx(desc, ctx);
                                     cli_rmdirs(dir);
                                     free(dir);
                                     closedir(dd);
                                     free(fname);
                                     return ret;
                                 }
9d0b7ebd
 
288057e9
                                 if (vba)
                                     sigtool_vba_scandir(dir, hex_output, vba);
                                 destroy_ctx(desc, ctx);
                                 cli_rmdirs(dir);
                                 free(dir);
                             }
                         }
                     }
                     free(fname);
                 }
             }
         }
9d0b7ebd
     } else {
288057e9
         logg("!Can't open directory %s.\n", dirname);
         return CL_EOPEN;
9d0b7ebd
     }
 
288057e9
     closedir(dd);
9d0b7ebd
     return 0;
 }
 
288057e9
 int sigtool_vba_scandir(const char *dirname, int hex_output, struct uniq *U)
9d0b7ebd
 {
49df8ea7
     cl_error_t status = CL_CLEAN;
     cl_error_t ret;
02840644
     int i, fd;
     size_t data_len;
49df8ea7
     vba_project_t *vba_project = NULL;
9d0b7ebd
     DIR *dd;
     struct dirent *dent;
a2a004df
     STATBUF statbuf;
53ed2cb7
     char *fullname, vbaname[1024], *hash;
9d0b7ebd
     unsigned char *data;
53ed2cb7
     uint32_t hashcnt;
859b6fb8
     unsigned int j;
9d0b7ebd
 
49df8ea7
     if (CL_SUCCESS != (ret = uniq_get(U, "_vba_project", 12, NULL, &hashcnt))) {
         logg("!ScanDir -> uniq_get('_vba_project') failed.\n");
         return ret;
     }
 
     while (hashcnt) {
         if (!(vba_project = (vba_project_t *)cli_vba_readdir(dirname, U, hashcnt))) {
             hashcnt--;
             continue;
         }
9d0b7ebd
 
288057e9
         for (i = 0; i < vba_project->count; i++) {
             for (j = 0; j < vba_project->colls[i]; j++) {
                 snprintf(vbaname, 1024, "%s" PATHSEP "%s_%u", vba_project->dir, vba_project->name[i], j);
                 vbaname[sizeof(vbaname) - 1] = '\0';
49df8ea7
 
                 fd = open(vbaname, O_RDONLY | O_BINARY);
288057e9
                 if (fd == -1) continue;
                 data = (unsigned char *)cli_vba_inflate(fd, vba_project->offset[i], &data_len);
                 close(fd);
9d0b7ebd
 
288057e9
                 if (data) {
                     data           = (unsigned char *)realloc(data, data_len + 1);
                     data[data_len] = '\0';
                     printf("-------------- start of code ------------------\n%s\n-------------- end of code ------------------\n", data);
                     free(data);
                 }
             }
         }
9d0b7ebd
 
49df8ea7
         cli_free_vba_project(vba_project);
         vba_project = NULL;
 
         hashcnt--;
72ce4b70
     }
 
49df8ea7
     if (CL_SUCCESS != (ret = uniq_get(U, "powerpoint document", 19, &hash, &hashcnt))) {
         logg("!ScanDir -> uniq_get('powerpoint document') failed.\n");
         return ret;
     }
 
     while (hashcnt) {
         snprintf(vbaname, 1024, "%s" PATHSEP "%s_%u", dirname, hash, hashcnt);
         vbaname[sizeof(vbaname) - 1] = '\0';
 
         fd = open(vbaname, O_RDONLY | O_BINARY);
         if (fd == -1) {
             hashcnt--;
             continue;
         }
         if ((fullname = cli_ppt_vba_read(fd, NULL))) {
             sigtool_scandir(fullname, hex_output);
             cli_rmdirs(fullname);
             free(fullname);
288057e9
         }
49df8ea7
         close(fd);
         hashcnt--;
72ce4b70
     }
 
49df8ea7
     if (CL_SUCCESS != (ret = uniq_get(U, "worddocument", 12, &hash, &hashcnt))) {
         logg("!ScanDir -> uniq_get('worddocument') failed.\n");
         return ret;
     }
9d0b7ebd
 
49df8ea7
     while (hashcnt) {
         snprintf(vbaname, sizeof(vbaname), "%s" PATHSEP "%s_%u", dirname, hash, hashcnt);
         vbaname[sizeof(vbaname) - 1] = '\0';
72ce4b70
 
49df8ea7
         fd = open(vbaname, O_RDONLY | O_BINARY);
         if (fd == -1) {
             hashcnt--;
             continue;
         }
288057e9
 
49df8ea7
         if (!(vba_project = (vba_project_t *)cli_wm_readdir(fd))) {
288057e9
             close(fd);
49df8ea7
             hashcnt--;
             continue;
         }
 
         for (i = 0; i < vba_project->count; i++) {
             data_len = vba_project->length[i];
02840644
             data     = (unsigned char *)cli_wm_decrypt_macro(fd, vba_project->offset[i], (uint32_t)data_len, vba_project->key[i]);
49df8ea7
             if (data) {
                 data           = (unsigned char *)realloc(data, data_len + 1);
                 data[data_len] = '\0';
                 printf("-------------- start of code ------------------\n%s\n-------------- end of code ------------------\n", data);
                 free(data);
             }
288057e9
         }
49df8ea7
 
         close(fd);
         cli_free_vba_project(vba_project);
         vba_project = NULL;
         hashcnt--;
9d0b7ebd
     }
 
288057e9
     if ((dd = opendir(dirname)) != NULL) {
         while ((dent = readdir(dd))) {
             if (dent->d_ino) {
                 if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
                     /* build the full name */
                     fullname = calloc(strlen(dirname) + strlen(dent->d_name) + 2, sizeof(char));
                     sprintf(fullname, "%s" PATHSEP "%s", dirname, dent->d_name);
9d0b7ebd
 
288057e9
                     /* stat the file */
                     if (LSTAT(fullname, &statbuf) != -1) {
                         if (S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode))
                             sigtool_vba_scandir(fullname, hex_output, U);
                     }
                     free(fullname);
                 }
             }
         }
9d0b7ebd
     } else {
288057e9
         logg("!ScanDir -> Can't open directory %s.\n", dirname);
         return CL_EOPEN;
9d0b7ebd
     }
 
288057e9
     closedir(dd);
49df8ea7
     return status;
9d0b7ebd
 }