Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

614
Vistas
Cómo implementar IAmsiStream para admitir la ejecución de un análisis de malware en Windows en una secuencia

Al implementar un IAmsiStream para realizar un análisis con Windows Defender, en archivos de más de ~20 MB, falla y Value does not fall within the expected range. .

¿Qué le falta a esta implementación?

 public class AmsiStream : IAmsiStream { private readonly Stream _input; private readonly string _name; private static readonly byte[] _nullPtr = new byte[Marshal.SizeOf(IntPtr.Zero)]; public AmsiStream(Stream input, string name) { _input = input ?? throw new ArgumentNullException(nameof(input)); _name = name ?? throw new ArgumentNullException(nameof(name)); } public int GetAttribute(AMSI_ATTRIBUTE attribute, int dataSize, byte[] data, out int retData) { const int E_NOTIMPL = unchecked((int)0x80004001); const int E_NOT_SUFFICIENT_BUFFER = unchecked((int)0x8007007A); byte[] bytes = { }; int retValue = 0; switch (attribute) { case AMSI_ATTRIBUTE.AMSI_ATTRIBUTE_APP_NAME: bytes = Encoding.Unicode.GetBytes("TestAmsi" + "\0"); break; case AMSI_ATTRIBUTE.AMSI_ATTRIBUTE_CONTENT_NAME: bytes = Encoding.Unicode.GetBytes(_name + "\0"); break; case AMSI_ATTRIBUTE.AMSI_ATTRIBUTE_CONTENT_SIZE: bytes = BitConverter.GetBytes((ulong)_input.Length); break; case AMSI_ATTRIBUTE.AMSI_ATTRIBUTE_SESSION: bytes = _nullPtr; break; case AMSI_ATTRIBUTE.AMSI_ATTRIBUTE_CONTENT_ADDRESS: retValue = E_NOTIMPL; break; default: retValue = E_NOTIMPL; break; } retData = 0; if (retValue == 0) { retData = bytes.Length; if (dataSize < bytes.Length) return E_NOT_SUFFICIENT_BUFFER; Array.Copy(bytes, data, bytes.Length); } return retValue; } public int Read(long position, int size, byte[] buffer, out int readSize) { _input.Seek(position, SeekOrigin.Begin); readSize = _input.Read(buffer, 0, size); return 0; } }

Un caso de prueba es:

 [Fact] public void TestWithLargeFile() { const long k = 1024; const long m = 1024 * k; const long fileSize = 21 * m; var c = new Random(42); var fileBuffer = new byte[fileSize]; c.NextBytes(fileBuffer); Equal(AMSI_RESULT.AMSI_RESULT_CLEAN, ScanInternal(new MemoryStream(fileBuffer), "test.file.txt")); } private AMSI_RESULT ScanInternal(Stream streamToCheck, string fileName) { var scanner = (IAntiMalware)new CAntiMalware(); var stream = new AmsiStream(streamToCheck, fileName); var result = scanner.Scan(stream, out AMSI_RESULT scanResult, out IAntiMalwareProvider _); if (result != (ulong)HResult.S_OK) { throw new InvalidOperationException($"Malware scan returned not OK: {result}"); } return scanResult; }

Código fuente completo para esta prueba en este repositorio de github

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

En su lugar, use MalwareScanner de: https://github.com/NewOrbit/MalwareScan.AMSI

var scanner = new MalwareScanner("MyApplications Viruscanner"); var result = scanner.HasVirus(stream, filename);

o para escanear un segmento de bytes de archivo grande entrante por segmento de bytes, consulte:

WindowsCOMAntiMalware: https://github.com/bsmg/BeatSaber-IPA-Reloaded/blob/master/IPA.Loader/AntiMalware/_HideInNet3/WindowsCOMAntiMalware.cs

con 2 implementaciones de IAmsiStream:

AmsiMemoryStream: https://github.com/bsmg/BeatSaber-IPA-Reloaded/blob/master/IPA.Loader/AntiMalware/_HideInNet3/ComAPI/AmsiMemoryStream.cs AmsiFileStream: https://github.com/bsmg/BeatSaber-IPA -Reloaded/blob/master/IPA.Loader/AntiMalware/_HideInNet3/ComAPI/AmsiFileStream.cs

PD: el límite de 16 mb no se encuentra en los documentos oficiales, no creo que sea una limitación de IAmsiStream, IAmsiStream se pasa a IAntimalwareProvider, que es una implementación del proveedor y tal vez el problema esté ahí; debe probar con otro proveedor para ver si obtiene el mismo error:

  • Eset: https://help.eset.com/ees/6/en-US/index.html?idh_config_antivirus.htm
  • AVG: https://malwaretips.com/threads/avg-antimalware-scan-interface.56180/
  • Kaspersky: https://support.kaspersky.com/KESWin/11.1.0/en-US/174819.htm
over 4 years ago · Santiago Trujillo Denunciar

0

No creo que pueda transmitir un archivo grande al proveedor de Windows Defender. Según este subproceso de github , parece haber un límite implementado por la plataforma de que si no maneja AMSI_ATTRIBUTE_CONTENT_ADDRESS en GetAttribute , el tamaño máximo de búfer pasado en el método de Read es de 16 MB. Y el propósito del método Read no es transmitir, sino que

Solicita un búfer lleno de contenido para leer.

El código de muestra (C++) proporcionado por Microsoft tampoco puede manejar archivos que superen este límite de tamaño.

Los documentos para desarrolladores de Microsoft declararon:

AMSI está diseñado en particular para combatir el "malware sin archivos"

cual

existe exclusivamente como un artefacto basado en la memoria de la computadora

según Wikipedia .

Para mí, si el tamaño del archivo es superior a 16 MB, puede cargarlo en la memoria y devolver la dirección del búfer manejando AMSI_ATTRIBUTE_CONTENT_ADDRESS . Y para archivos grandes, podría considerar usar un archivo mapeado en memoria :

 public unsafe int GetAttribute(AMSI_ATTRIBUTE attribute, int dataSize, [Out]byte[] data, [Out]out int retData) { ... case AMSI_ATTRIBUTE_CONTENT_ADDRESS: retData = sizeof(IntPtr); if (dataSize < retData) { return E_NOT_SUFFICIENT_BUFFER; } // This is an example // Better to open in constructor and close in Dispose var mappedFile = MemoryMappedFile.CreateFromFile(_name, FileMode.Open); var mappedFileAccessor = mappedFile.CreateViewAccessor(0, fileSize); byte* fileContent = null; mappedFileAccessor.SafeMemoryMappedViewHandle.AcquirePointer(ref fileContent); fixed (byte* pData = data) { *(IntPtr*) pData = (IntPtr)fileContent; } return 0; ... }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda