mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2025-10-19 18:33:16 +00:00

The header parsing / executable metadata collecting functions for the PE, ELF, and Mach-O file types were using `int` for the return type. Mostly they were returning 0 for success and -1, -2, -3, or -4 for failure. But in some cases they were returning cl_error_t enum values for failure. Regardless, the function using them was treating 0 as success and non-zero as failure, which it stored as -1 ... every time. This commit switches them all to use cl_error_t. I am continuing to storeo the final result as 0 / -1 in the `peinfo` struct, but outside of that everything has been made consistent. While I was working on that, I got a tad side tracked. I noticed that the target type isn't an enum, or even a set of #defines. So I made an enum and then changed the code that uses target types to use the enum. I also removed the `target` parameter from a number of functions that don't actually use it at all. Some recursion was masking the fact that it was an unused parameter which is why there was no warning about it.
1362 lines
42 KiB
C
1362 lines
42 KiB
C
/*
|
|
* 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
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*/
|
|
|
|
#if HAVE_CONFIG_H
|
|
#include "clamav-config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <dirent.h>
|
|
#include <ctype.h>
|
|
|
|
// libclamav
|
|
#include "clamav.h"
|
|
#include "vba_extract.h"
|
|
#include "ole2_extract.h"
|
|
#include "readdb.h"
|
|
#include "clamav_rust.h"
|
|
|
|
// common
|
|
#include "output.h"
|
|
|
|
#include "vba.h"
|
|
|
|
typedef struct mac_token_tag {
|
|
unsigned char token;
|
|
const char *str;
|
|
} mac_token_t;
|
|
|
|
typedef struct mac_token2_tag {
|
|
uint16_t token;
|
|
const char *str;
|
|
|
|
} mac_token2_t;
|
|
|
|
cli_ctx *convenience_ctx(int fd)
|
|
{
|
|
cl_error_t status = CL_EMEM;
|
|
cli_ctx *ctx = NULL;
|
|
struct cl_engine *engine = NULL;
|
|
cl_fmap_t *new_map = 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;
|
|
}
|
|
|
|
if (cli_add_content_match_pattern(engine->root[0], "test", "deadbeef", 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;
|
|
}
|
|
|
|
/* fake input fmap */
|
|
new_map = fmap(fd, 0, 0, NULL);
|
|
if (NULL == new_map) {
|
|
printf("convenience_ctx: fmap failed\n");
|
|
goto done;
|
|
}
|
|
|
|
/* prepare context */
|
|
ctx = cli_calloc(1, sizeof(cli_ctx));
|
|
if (!ctx) {
|
|
printf("convenience_ctx: ctx allocation failed\n");
|
|
goto done;
|
|
}
|
|
|
|
ctx->engine = (const struct cl_engine *)engine;
|
|
|
|
ctx->evidence = evidence_new();
|
|
|
|
ctx->dconf = (struct cli_dconf *)engine->dconf;
|
|
|
|
ctx->recursion_stack_size = ctx->engine->max_recursion_level;
|
|
ctx->recursion_stack = cli_calloc(sizeof(recursion_level_t), ctx->recursion_stack_size);
|
|
if (!ctx->recursion_stack) {
|
|
status = CL_EMEM;
|
|
goto done;
|
|
}
|
|
|
|
// ctx was calloc'd, so recursion_level starts at 0.
|
|
ctx->recursion_stack[ctx->recursion_level].fmap = new_map;
|
|
ctx->recursion_stack[ctx->recursion_level].type = CL_TYPE_ANY; // ANY for the top level, because we don't yet know the type.
|
|
ctx->recursion_stack[ctx->recursion_level].size = new_map->len;
|
|
|
|
ctx->fmap = ctx->recursion_stack[ctx->recursion_level].fmap;
|
|
|
|
ctx->options = cli_calloc(1, sizeof(struct cl_scan_options));
|
|
if (!ctx->options) {
|
|
printf("convenience_ctx: scan options allocation failed\n");
|
|
goto done;
|
|
}
|
|
ctx->options->general |= CL_SCAN_GENERAL_HEURISTICS;
|
|
ctx->options->parse = ~(0);
|
|
|
|
status = CL_SUCCESS;
|
|
|
|
done:
|
|
if (CL_SUCCESS != status) {
|
|
if (NULL != new_map) {
|
|
funmap(new_map);
|
|
}
|
|
if (NULL != ctx) {
|
|
if (NULL != ctx->options) {
|
|
free(ctx->options);
|
|
}
|
|
if (NULL != ctx->recursion_stack) {
|
|
free(ctx->recursion_stack);
|
|
}
|
|
free(ctx);
|
|
ctx = NULL;
|
|
}
|
|
if (NULL != engine) {
|
|
cl_engine_free(engine);
|
|
}
|
|
}
|
|
|
|
return ctx;
|
|
}
|
|
|
|
void destroy_ctx(cli_ctx *ctx)
|
|
{
|
|
if (NULL != ctx) {
|
|
if (NULL != ctx->recursion_stack) {
|
|
/* Clean up any fmaps */
|
|
while (ctx->recursion_level > 0) {
|
|
if (NULL != ctx->recursion_stack[ctx->recursion_level].fmap) {
|
|
funmap(ctx->recursion_stack[ctx->recursion_level].fmap);
|
|
ctx->recursion_stack[ctx->recursion_level].fmap = NULL;
|
|
}
|
|
ctx->recursion_level -= 1;
|
|
}
|
|
if (NULL != ctx->recursion_stack[0].fmap) {
|
|
funmap(ctx->recursion_stack[0].fmap);
|
|
ctx->recursion_stack[0].fmap = NULL;
|
|
}
|
|
|
|
free(ctx->recursion_stack);
|
|
ctx->recursion_stack = 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->evidence) {
|
|
evidence_free(ctx->evidence);
|
|
}
|
|
|
|
free(ctx);
|
|
}
|
|
}
|
|
|
|
int sigtool_vba_scandir(const char *dirname, int hex_output, struct uniq *U);
|
|
|
|
static char *get_unicode_name(char *name, int size)
|
|
{
|
|
int i, j;
|
|
char *newname;
|
|
|
|
if (*name == 0 || size <= 0) {
|
|
return NULL;
|
|
}
|
|
|
|
newname = (char *)malloc(size * 2);
|
|
if (!newname) {
|
|
return NULL;
|
|
}
|
|
j = 0;
|
|
for (i = 0; i < size; i = i + 2) {
|
|
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++] = '_';
|
|
}
|
|
}
|
|
newname[j] = '\0';
|
|
return newname;
|
|
}
|
|
|
|
static void output_token(unsigned char token)
|
|
{
|
|
int i;
|
|
mac_token_t mac_token[] = {
|
|
{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},
|
|
};
|
|
|
|
for (i = 0; mac_token[i].token != 0x00; i++) {
|
|
if (token == mac_token[i].token) {
|
|
printf(" %s ", mac_token[i].str);
|
|
return;
|
|
}
|
|
}
|
|
printf("[#0x%x]", token);
|
|
return;
|
|
}
|
|
|
|
static void output_token67(uint16_t token)
|
|
{
|
|
int i;
|
|
mac_token2_t mac_token[] = {
|
|
{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},
|
|
};
|
|
for (i = 0; mac_token[i].token != 0x0000; i++) {
|
|
if (token == mac_token[i].token) {
|
|
printf("%s", mac_token[i].str);
|
|
return;
|
|
}
|
|
}
|
|
printf("[#67(0x%x)]", token);
|
|
return;
|
|
}
|
|
|
|
static void output_token73(uint16_t token)
|
|
{
|
|
int i;
|
|
mac_token2_t mac_token[] = {
|
|
{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},
|
|
};
|
|
|
|
for (i = 0; mac_token[i].token != 0x0000; i++) {
|
|
if (token == mac_token[i].token) {
|
|
printf("%s", mac_token[i].str);
|
|
return;
|
|
}
|
|
}
|
|
printf("[#73(0x%x)]", token);
|
|
return;
|
|
}
|
|
|
|
static void print_hex_buff(unsigned char *start, unsigned char *end, int hex_output)
|
|
{
|
|
if (!hex_output) {
|
|
return;
|
|
}
|
|
printf("[clam hex:");
|
|
while (start < end) {
|
|
printf(" %.2x", *start);
|
|
start++;
|
|
}
|
|
printf("]\n");
|
|
}
|
|
|
|
#ifdef __GNUC__
|
|
static void wm_decode_macro(unsigned char *buff, uint32_t len, int hex_output) __attribute__((unused));
|
|
#endif
|
|
static void wm_decode_macro(unsigned char *buff, uint32_t len, int hex_output)
|
|
{
|
|
uint32_t i;
|
|
uint8_t s_length, j;
|
|
uint16_t w_length, int_val;
|
|
unsigned char *tmp_buff, *tmp_name, *line_start;
|
|
|
|
i = 2;
|
|
line_start = buff;
|
|
while (i < len) {
|
|
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;
|
|
|
|
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;
|
|
|
|
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;
|
|
}
|
|
}
|
|
print_hex_buff(line_start, buff + i, hex_output);
|
|
}
|
|
|
|
static int sigtool_scandir(const char *dirname, int hex_output)
|
|
{
|
|
int status = -1;
|
|
DIR *dd = NULL;
|
|
struct dirent *dent;
|
|
STATBUF statbuf;
|
|
const char *tmpdir;
|
|
char *fname = NULL;
|
|
char *dir = NULL;
|
|
cl_error_t ret = CL_CLEAN;
|
|
int desc = -1;
|
|
cli_ctx *ctx = NULL;
|
|
int has_vba = 0, has_xlm = 0;
|
|
|
|
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) {
|
|
status = -1;
|
|
goto done;
|
|
}
|
|
|
|
sprintf(fname, "%s" PATHSEP "%s", dirname, dent->d_name);
|
|
|
|
/* 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)) {
|
|
status = CL_VIRUS;
|
|
goto done;
|
|
}
|
|
} else {
|
|
if (S_ISREG(statbuf.st_mode)) {
|
|
struct uniq *files = NULL;
|
|
tmpdir = cli_gettmpdir();
|
|
|
|
/* generate the temporary directory */
|
|
dir = cli_gentemp(tmpdir);
|
|
if (!dir) {
|
|
printf("cli_gentemp() failed\n");
|
|
status = -1;
|
|
goto done;
|
|
}
|
|
|
|
if (mkdir(dir, 0700)) {
|
|
printf("Can't create temporary directory %s\n", dir);
|
|
status = CL_ETMPDIR;
|
|
goto done;
|
|
}
|
|
|
|
if ((desc = open(fname, O_RDONLY | O_BINARY)) == -1) {
|
|
printf("Can't open file %s\n", fname);
|
|
status = 1;
|
|
goto done;
|
|
}
|
|
|
|
if (!(ctx = convenience_ctx(desc))) {
|
|
status = 1;
|
|
goto done;
|
|
}
|
|
if ((ret = cli_ole2_extract(dir, ctx, &files, &has_vba, &has_xlm, NULL))) {
|
|
printf("ERROR %s\n", cl_strerror(ret));
|
|
|
|
status = ret;
|
|
goto done;
|
|
}
|
|
|
|
if (has_vba && files)
|
|
sigtool_vba_scandir(dir, hex_output, files);
|
|
|
|
// Cleanup
|
|
if (desc >= 0) {
|
|
close(desc);
|
|
desc = -1;
|
|
}
|
|
|
|
destroy_ctx(ctx);
|
|
ctx = NULL;
|
|
|
|
cli_rmdirs(dir);
|
|
free(dir);
|
|
dir = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Cleanup
|
|
free(fname);
|
|
fname = NULL;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
logg(LOGG_ERROR, "Can't open directory %s.\n", dirname);
|
|
return CL_EOPEN;
|
|
}
|
|
|
|
status = 0;
|
|
|
|
done:
|
|
if (desc >= 0) {
|
|
close(desc);
|
|
}
|
|
if (NULL != dd) {
|
|
closedir(dd);
|
|
}
|
|
if (NULL != ctx) {
|
|
destroy_ctx(ctx);
|
|
}
|
|
if (NULL != dir) {
|
|
cli_rmdirs(dir);
|
|
free(dir);
|
|
}
|
|
if (NULL != fname) {
|
|
free(fname);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
int sigtool_vba_scandir(const char *dirname, int hex_output, struct uniq *U)
|
|
{
|
|
cl_error_t status = CL_CLEAN;
|
|
cl_error_t ret;
|
|
int i, fd;
|
|
size_t data_len;
|
|
vba_project_t *vba_project = NULL;
|
|
DIR *dd;
|
|
struct dirent *dent;
|
|
STATBUF statbuf;
|
|
char *fullname, vbaname[1024], *hash;
|
|
unsigned char *data;
|
|
uint32_t hashcnt;
|
|
unsigned int j;
|
|
|
|
if (CL_SUCCESS != (ret = uniq_get(U, "_vba_project", 12, NULL, &hashcnt))) {
|
|
logg(LOGG_ERROR, "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;
|
|
}
|
|
|
|
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';
|
|
|
|
fd = open(vbaname, O_RDONLY | O_BINARY);
|
|
if (fd == -1) continue;
|
|
data = (unsigned char *)cli_vba_inflate(fd, vba_project->offset[i], &data_len);
|
|
close(fd);
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
cli_free_vba_project(vba_project);
|
|
vba_project = NULL;
|
|
|
|
hashcnt--;
|
|
}
|
|
|
|
if (CL_SUCCESS != (ret = uniq_get(U, "powerpoint document", 19, &hash, &hashcnt))) {
|
|
logg(LOGG_ERROR, "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);
|
|
}
|
|
close(fd);
|
|
hashcnt--;
|
|
}
|
|
|
|
if (CL_SUCCESS != (ret = uniq_get(U, "worddocument", 12, &hash, &hashcnt))) {
|
|
logg(LOGG_ERROR, "ScanDir -> uniq_get('worddocument') failed.\n");
|
|
return ret;
|
|
}
|
|
|
|
while (hashcnt) {
|
|
snprintf(vbaname, sizeof(vbaname), "%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 (!(vba_project = (vba_project_t *)cli_wm_readdir(fd))) {
|
|
close(fd);
|
|
hashcnt--;
|
|
continue;
|
|
}
|
|
|
|
for (i = 0; i < vba_project->count; i++) {
|
|
data_len = vba_project->length[i];
|
|
data = (unsigned char *)cli_wm_decrypt_macro(fd, vba_project->offset[i], (uint32_t)data_len, vba_project->key[i]);
|
|
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);
|
|
}
|
|
}
|
|
|
|
close(fd);
|
|
cli_free_vba_project(vba_project);
|
|
vba_project = NULL;
|
|
hashcnt--;
|
|
}
|
|
|
|
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);
|
|
|
|
/* 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);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
logg(LOGG_ERROR, "ScanDir -> Can't open directory %s.\n", dirname);
|
|
return CL_EOPEN;
|
|
}
|
|
|
|
closedir(dd);
|
|
return status;
|
|
}
|