Paul,
I don't' see a reason for it happening and it seems a first rate bug to me. The code is "finding" text and replacing that text with itself with a different font attribute. There is nothing it the code that I see that should cause bookmarks to shift to the left.
As I said, the code is clunky to begin with. Now it is even more clunky restoring the bookmarks

:
Code:
Sub ReverseBoldIII()
Application.ScreenUpdating = False
Dim oRI As Range, oRng As Range
Dim oCol As New Collection
Dim oBM As Bookmark
Dim lngIndex As Long
Dim arrRng() As String
For Each oBM In Selection.Range.Bookmarks
oCol.Add oBM.Start & "|" & oBM.End
Next
Set oRng = Selection.Range.Duplicate
Set oRI = Selection.Range.Duplicate
With oRng.Find
.Text = "*"
.Font.Bold = False
.MatchWildcards = True
With .Replacement
.Text = "^&"
.Font.Bold = True
.Font.DoubleStrikeThrough = True 'any unused font attribute
End With
.Execute Replace:=wdReplaceAll
End With
Set oRng = Selection.Range.Duplicate
With oRng.Find
.Text = "*"
.Font.Bold = True
.Font.DoubleStrikeThrough = False
.MatchWildcards = True
With .Replacement
.Text = "^&"
.Font.Bold = False
End With
.Execute Replace:=wdReplaceAll
End With
Set oRng = Selection.Range.Duplicate
oRng.Select
With oRng.Find
.Text = "*"
.Font.Bold = True
.Font.DoubleStrikeThrough = True
.MatchWildcards = True
With .Replacement
.Text = "^&"
.Font.DoubleStrikeThrough = False
End With
.Execute Replace:=wdReplaceAll
End With
Set oRng = Selection.Range
For lngIndex = 1 To oCol.Count
Set oBM = oRI.Bookmarks(lngIndex)
arrRng = Split(oCol.Item(lngIndex), "|")
oBM.Start = arrRng(LBound(arrRng))
oBM.End = arrRng(UBound(arrRng))
Next
Application.ScreenUpdating = True
End Sub