module Fux2
#~   获取指定模块的校验值
#~   用于确保模块符合预期
#~   使用Fux2::SteamTools.get_dll_checksum(moduleName)获取模块校验值
#~   注意:无法正确对加密、自解压模块生效
#~   by Fux2
#~   欢迎访问 [url]https://rpg.blue/[/url] 获取更多资源
  module SteamTools
    
    GetModuleHandle = Win32API.new('kernel32','GetModuleHandle','p','l')
    WriteProcessMemoryR = Win32API.new('kernel32','WriteProcessMemory','lplll','i')
    
    def self.get_dll_checksum(fn)
      dll = GetModuleHandle.call(fn)
      return 0 if dll==0
      buffer = "\0"*2
      WriteProcessMemoryR.call(-1,buffer,dll,2,0)
      return 0 if buffer != "MZ"
      buffer = "\0"*4
      WriteProcessMemoryR.call(-1,buffer,dll+0x3C,4,0)
      offset = buffer.unpack("L").first
      WriteProcessMemoryR.call(-1,buffer,dll+offset,4,0)
      sign = buffer.unpack("L").first
      return 0 if sign != 0x4550
      WriteProcessMemoryR.call(-1,buffer,dll+offset+0x2C,4,0)
      base = buffer.unpack("L").first
      WriteProcessMemoryR.call(-1,buffer,dll+offset+0x1C,4,0)
      size = buffer.unpack("L").first / 4 * 4
      code = "\0" * size
      WriteProcessMemoryR.call(-1,code,dll+base,size,0)
      code = code.unpack("C*")
      buffer = "\0" * 8
      WriteProcessMemoryR.call(-1,buffer,dll+offset+0xA0,8,0)
      vad,vas = *buffer.unpack("L*")
      reloadaddr = dll+vad
      endAddr = base+size
      loop do
        WriteProcessMemoryR.call(-1,buffer,reloadaddr,8,0)
        rad,ras = *buffer.unpack("L*")
        break if ras == 0
        if rad+ras>=base && rad> 12
            ofs = byte & 0xFFF
            index = rad+ofs-base
            break if index<0 || index>=size
            code[index,4] = [0,0,0,0]
          end
        end
        reloadaddr += ras
      end
      return code.inject(:+)
    end
  end
  
end
# sum = Fux2::SteamTools.get_dll_checksum("steam_api.dll")
# raise 'Illegal DLL file detected' unless sum==12800700