Coverage for /pythoncovmergedfiles/medio/medio/src/pyvex/fuzzing/irsb_fuzzer.py: 52%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

58 statements  

1###### Coverage stub 

2import atexit 

3import coverage 

4cov = coverage.coverage(data_file='.coverage', cover_pylib=True) 

5cov.start() 

6# Register an exist handler that will print coverage 

7def exit_handler(): 

8 cov.stop() 

9 cov.save() 

10atexit.register(exit_handler) 

11####### End of coverage stub 

12#!/usr/bin/python3 

13# Copyright 2023 Google LLC 

14# 

15# Licensed under the Apache License, Version 2.0 (the "License"); 

16# you may not use this file except in compliance with the License. 

17# You may obtain a copy of the License at 

18# 

19# http://www.apache.org/licenses/LICENSE-2.0 

20# 

21# Unless required by applicable law or agreed to in writing, software 

22# distributed under the License is distributed on an "AS IS" BASIS, 

23# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

24# See the License for the specific language governing permissions and 

25# limitations under the License. 

26# 

27################################################################################ 

28import re 

29import sys 

30from contextlib import contextmanager 

31from enum import IntEnum 

32from io import StringIO 

33 

34import atheris 

35 

36with atheris.instrument_imports(include=["pyvex"]): 

37 import pyvex 

38 

39# Additional imports 

40from enhanced_fdp import EnhancedFuzzedDataProvider 

41 

42register_error_msg = re.compile("Register .*? does not exist!") 

43 

44 

45@contextmanager 

46def nostdout(): 

47 saved_stdout = sys.stdout 

48 saved_stderr = sys.stderr 

49 sys.stdout = StringIO() 

50 sys.stderr = StringIO() 

51 yield 

52 sys.stdout = saved_stdout 

53 sys.stderr = saved_stderr 

54 

55 

56# Save all available architectures off 

57available_archs = [ 

58 pyvex.ARCH_X86, 

59 pyvex.ARCH_AMD64, 

60 pyvex.ARCH_ARM_LE, 

61 pyvex.ARCH_ARM_BE, 

62 pyvex.ARCH_ARM64_LE, 

63 pyvex.ARCH_ARM64_BE, 

64 pyvex.ARCH_PPC32, 

65 pyvex.ARCH_PPC64_BE, 

66 pyvex.ARCH_PPC64_LE, 

67 pyvex.ARCH_S390X, 

68 pyvex.ARCH_MIPS32_BE, 

69 pyvex.ARCH_MIPS32_LE, 

70 pyvex.ARCH_MIPS64_BE, 

71 pyvex.ARCH_MIPS64_LE, 

72] 

73 

74 

75class SupportedOptLevels(IntEnum): 

76 """ 

77 Enumerates the supported optimization levels within pyvex, as derived from the documentation 

78 """ 

79 

80 StrictUnopt = -1 

81 Unopt = 0 

82 Opt = 1 

83 StrictOpt = 2 

84 

85 

86def consume_random_arch(fdp: atheris.FuzzedDataProvider) -> pyvex.arches.PyvexArch: 

87 return fdp.PickValueInList(available_archs) 

88 

89 

90def TestOneInput(data: bytes): 

91 fdp = EnhancedFuzzedDataProvider(data) 

92 

93 arch = consume_random_arch(fdp) 

94 

95 try: 

96 with nostdout(): 

97 data = fdp.ConsumeRandomBytes() 

98 max_bytes = fdp.ConsumeIntInRange(0, len(data)) 

99 irsb = pyvex.lift( 

100 data, 

101 fdp.ConsumeInt(arch.bits), 

102 arch, 

103 max_bytes=fdp.ConsumeIntInRange(0, len(data)), 

104 max_inst=fdp.ConsumeInt(16), 

105 bytes_offset=fdp.ConsumeIntInRange(0, max_bytes), 

106 opt_level=fdp.PickValueInEnum(SupportedOptLevels), 

107 ) 

108 irsb.pp() 

109 return 0 

110 except pyvex.PyVEXError: 

111 return -1 

112 except ValueError as e: 

113 if re.match(register_error_msg, str(e)): 

114 return -1 

115 raise e 

116 except OverflowError: 

117 return -1 

118 

119 

120def main(): 

121 atheris.Setup(sys.argv, TestOneInput) 

122 atheris.Fuzz() 

123 

124 

125if __name__ == "__main__": 

126 main()