Python 3, 166 162 161 bytes
lambda p,r=range:[chr(int(''.join(str(+([n*2for n in p+p][y+i//3-1][x+i%3-1]=='X'))for i in r(9)if i-4),2))for y in r(len(p))for x in r(len(p[0]))if'X'==p[y][x]]
Takes as input a list of strings and returns a character array.
Ungolfed (sorta):
def f(p):
chars = []
for y in range(len(p)):
for x in range(len(p[0])):
if p[y][x] != 'X':
continue
bits = []
for i in range(9):
if i == 4:
continue
bit_x = x + i%3 - 1
bit_y = y + i//3 - 1
char_at_cell = [n*2for n in p+p][bit_y][bit_x]
bit = str(+(char_at_cell=='X'))
bits.append(bit)
char_code = int(''.join(bits), 2)
chars.append(chr(char_code))
return chars
Edit: made shorter by 5 bytes thanks to Jo King and Jonathan FrenchFrech